2023-03-02 11:12:31

在进行一些敏感操作时,比如删除用户或修改密码,服务器如何知道当前用户是否有权限?很明显:用户必须已经登录。

但客户端和服务器之间使用的是 HTTP 协议,而 HTTP 协议是无状态的。

无状态

服务器无法判断当前请求的用户和之前登录成功的用户是否是同一个人。

解决方案

  1. 登录成功后,服务器给客户端颁发一个凭证(类似工牌)
  2. 后续每次请求时,客户端都需要携带这个凭证

但用户通常会在多个网站上登录,因此需要一个能够管理多个凭证的工具,需要满足以下条件:

  1. 管理多个网站的凭证
  2. 访问不同网站时,自动携带对应的凭证
  3. 能够删除过期的凭证

满足这些需求的技术就是 Cookie

每个 Cookie 记录着对应网站的一些信息,包含以下字段:

  • keyCookie 的名称
  • valueCookie 的值
  • domain:域,表示该 Cookie 属于哪个网站,例如 baidu.com
  • path:路径,表示该 Cookie 属于网站的哪个路径,如 /search 表示 Cookie 仅在该路径下有效
  • secure:是否仅用于安全传输
  • expire:过期时间

只有同时满足以下条件,Cookie 才会被附带在请求中发送到服务器:

  1. Cookie 未过期
  2. Cookie 的 domain 和请求的 domain 匹配
    • Cookie 的 domain 是 .baidu.com,可以匹配 baidu.comwww.baidu.coma.baidu.com
    • Cookie 的 domain 是 www.baidu.com,只能匹配 www.baidu.com
  3. Cookie 的 path 和请求的 path 匹配
    • Cookie 的 path 是 /flow,可以匹配 /flow/flow/a,但不能匹配 /blog
    • 如果 path 是 /,则可以匹配所有路径
  4. 安全传输验证
    • 如果 securetrue,请求协议必须是 https
    • 如果 securefalse,则不限制协议

Cookie 可以通过服务端或客户端设置。

服务端设置

通过响应头中的 Set-Cookie 字段进行设置:

Set-Cookie: cookie1
Set-Cookie: cookie2

客户端设置

客户端也可以直接设置 Cookie,但实际使用较少:

document.cookie = 'key=value; path=/; domain=example.com;'