🗒️HTTP Cookie

也称 web cookie、浏览器 cookie

HTTP Cookie 是 server 发送到用户浏览器的一小段数据。浏览器会存储 Cookie 并在以后的请求中将其发送回同一 server。通常,HTTP Cookie 用于判断两个请求是否来自同一浏览器(比如保持用户登录),将状态引入到无状态的 HTTP 事务中。

Cookie 通常是由 web 服务器创建,并由浏览器放置到用户计算机上的一小块数据。它让 web server 能够在用户设备上存储状态信息。

Cookie 就是服务器委托浏览器存储在客户端里的一些数据,而这些数据通常都会记录用户的关键识别信息,从而让服务器有了记忆能力。

工作原理

有了 cookie 之后,流程大约是:

  1. 当用户通过浏览器第一次访问服务器时,服务器肯定不知道它的身份。所以,就要创建一个独特的身份标识数据,放进 Set-Cookie header 里,然后随着响应报文一同发给浏览器

  2. 浏览器收到响应报文之后,看到里面有 Set-Cookie header,知道这是服务器给的身份标识,于是就保存起来,等下次再请求的时候就自动把这个值放进 Cookie header 里发给服务器

  3. 因为第二次请求里有了 Cookie header 字段,所以服务器就知道了这个用户不是新人,之前来过,便可以识别出用户的身份,然后提供个性化的服务

Request
Response
说明

Set-Cookie: key=value

可重复多个

Cookie

多个值之间用 ; 隔开

说明:由于 cookie 并不属于 HTTP 标准(RFC6265,而不是 RFC2616/7230),所以语法上和其它标头字段不一致,分隔符用的是 ; 而不是 ,

# response
Set-Cookie: k1=v1
Set-Cookie: k2=v2
# request
Cookie: k1=v1; k2=v2

然后,对于向 server 发出的每个后续 request,浏览器都会用 Cookie header 将所有先前存储的 cookie 发送回 server。仅发送 cookie 的名称和值,并不会带 cookie 的属性。

为了防止 cookie 被外泄和窃取,服务器可以设置以下属性。

生命周期

cookie 的生命周期,有两种定义方式:

  1. Session Cookie:当 current session 结束时,会被删除

  2. Permanent Cookie:过期时间由 Max-AgeExpires 属性来指定

    • Expires:绝对时间点,过期时间/截止日期,表示浏览器应删除 cookie 的特定日期和时间

    • Max-Age:相对时间,单位是秒,是相对于浏览器收到报文的时间点

    • 当两者同时存在时,Max-Age 的优先级更高

Set-Cookie: k3=v3; Max-Age=3
Set-Cookie: k4=v4; Expires=xxx; Secure; HttpOnly

作用域

cookie 的作用域:cookie 应发送到哪些 URL。

  1. Domain:指定哪些 host 可以接收 cookie

    • 如果没有指定该属性,浏览器会默认设置为所请求资源的相同 host,但不包括子域

    • 如果指定了该属性,则始终包含子域。比如 Domain=mozilla.org,则该 cookie 在子域上也能使用,比如 developer.mozilla.org

  2. Path:指定请求的 URL 中必须包含的 path。比如 Path=/docs

    • 则以下 request path 匹配:/docs, /docs/, /docs/Web/, /docs/Web/HTTP

    • 则以下 request path 不匹配:/, /docsets, /fr/docs

安全性

Set-Cookie: k1=v1; Expires=xxx; Secure; HttpOnly
  1. Secure:表示此 cookie 只能用于 HTTPS 协议,HTTP 会被禁止发送。但 cookie 本身不是加密的,浏览器里还是以明文的形式存在

  2. HttpOnly:表示此 cookie 只能通过 HTTP 协议传输,禁止其它访问方式。比如客户端就没法使用 JavaScript 的 document.cookie 等一切相关的 API 访问了,从而避免了 XSS 窃取 cookie

  3. SameSite:表示能否通过跨站点请求发送 cookie,可以防范 CSRF 攻击(跨站请求伪造)

    • SameSite=Strict 严格限定 cookie 不能随跳转链接跨站发送,浏览器只会将 cookie 发送到与源域相同的目标域

    • SameSite=Lax 略微宽松,允许 GET/HEAD 等安全方法,但禁止 POST 跨站发送

    • SameSite=None

有了 cookie,服务器就有了记忆能力,能够保存状态。

  1. 身份识别。保存用户的登录信息,实现有状态的会话事务

  2. 个性化:用户偏好、主题和其它设置

  3. 追踪:记录并分析用户行为

  4. 广告跟踪。这种 cookie 不是由访问的主站存储的,所以又叫 third-party cookie。为了防止滥用 cookie 搜集用户隐私,互联网组织相继提出了 DNT(Do Not Track)和 P3P(Platform for Privacy Preferences Project),但实际作用不大。

替代方案

一些可以使用 cookie 完成的操作,也可以用其它机制:

  1. 身份验证和会话管理

    1. HTTP 认证:基本访问认证、摘要访问认证协议

    2. JSON Web Token(JWT,JSON 网络令牌):一个独立的信息包

    3. URL 的查询字符串:由 server 将包含唯一会话标识符的查询字符串附加到网页内的所有链接组成

    4. 带有隐藏字段的 Web 表单:

    5. window.name DOM 属性

  2. 追踪

    1. 浏览器指纹

    2. HTTP ETag

    3. IP地址:并不可靠,因为有公共 IP

    4. 浏览器缓存

  3. 网络存储:Web Storage API、 IndexedDB

    • 值得一提的是,cookie 作为客户端存储的方式正在被淘汰中。客户端存储,更建议用现代存储 API:Web Storage API(localStorage + sessionStorage)和 IndexedDB

    • window.sessionStoragewindow.localStorage 属性在持续时间上分别对应:会话 cookie 和永久 cookie,但比 cookie 有更大的存储限制,并且永远不会发送到服务器

    • 而 IndexedDB API 可以存储更结构化、更大量的数据

https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies

Last updated