HTTP: Cookie

 20th August 2020 at 2:19pm

Cookie 是服务端给浏览器下发的一小串信息;浏览器收到之后,在后续的请求中都会将这串信息带给服务器,这使得服务端可以知道这些请求都来源于同个浏览器(往往也是同个用户)。

用途

来自 MDN

Session management
Logins, shopping carts, game scores, or anything else the server should remember
Personalization
User preferences, themes, and other settings
Tracking
Recording and analyzing user behavior

最常见的场景是 维持用户登录态 以及 实现购物车

在 web 技术还不足够发达时,cookie 也是实现浏览器端存储的唯一方式。但是后来发展出来的 Local Storage、Session Storage 和 IndexDB 取代了这一功能。

服务端如何下发 cookie?

在 HTTP 回包的头中加入 Set-CookieSet-Cookie2

HTTP/2.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

[page content]

Session cookies v.s. permanent cookies

没有设置过期时间的 cookie 即 session cookie,在浏览器关闭时会被清除:

# Session cookie
Set-Cookie: id=a3fWa;

# Permanent cookie
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

Security

带有 Secure 指令的 cookie,仅在网站是 HTTPS 协议时会被传输给服务端。但仍然不要在 cookie 中存放敏感信息,因为 Secure 带来的安全性,还依赖于服务端的 TLS 安全 做得是否到位。

带有 HttpOnly 指令的 cookie,无法被 JS API Document.cookie 获取。这可以避免在受到 XSS 攻击时被恶意代码获取。

关于 SameSite 字段,设计的目的是为了防 CSRF,在单独的 HTTP: Cookie: SameSite 中描述。

参考 OWASP 提供的 cookie security 内容。

Scope of cookies

DomainPath 指令被用来限定 cookie 的生效范围:

Set-Cookie: bid="FgXN3U9Vku4"; path=/; domain=.douban.com; expires=Fri, 16-Apr-2021 02:13:08 GMT

Domain

  • 如果不指定,则被默认为当面页面的 host,不包含 子域名(比如 developer.mozilla.org 之于 mozilla.org
  • 如果指定,则总是包含子域名
Note
在实际应用中,你经常会发现一些网站返回的是带有 . 开头的(如 .douban.com)。这是因为被废弃的老规范中,用 . 开头的才会包含子域名。但这一行为已经在现行的 RFC 6265 中被废除。网站为了兼容一些实现老规范的浏览器,会在开头加上 .,但这个 . 会被现代浏览器无视,跟没有加一样。

如果指定了 Path,则在访问它的子目录时该 cookie 都会被发送。比如指定了 Path=/docs,则对 /docs /docs/Web//docs/Web/HTTP 都生效。

Third-party cookies

第三方 cookie,即你在访问一个网页时,网页中的第三方内容(通常是广告追踪代码、Social login widget 等)写入的第三方网站 cookie,一般用来做广告追踪。

广告平台(如 Google AdSense)通过 JS 代码来获取用户设备、当前页面、地理位置等方方面面的信息。

大多数浏览器会有选项让你禁用第三方 cookie。这可能会影响网页功能。很多 AdBlocker 或者浏览器的隐私功能,会拦截第三方 cookie。

Apple 的 Intelligent Tracking Prevention 在防止第三方 cookie 上做得比较激进,以保护用户隐私。

参考:

Reference

TOC