每个 Cookie 都包含一个键值对,以及一些用于控制 Cookie 的使用时间和地点的属性。
SameSite
属性(在 RFC6265bis 中定义)的引入让您可以声明 Cookie 是否仅限于第一方或同一网站情境。了解此处“网站”的确切含义会很有帮助。
网站是域名后缀与域名前缀部分的组合。例如,www.web.dev
网域是 web.dev
网站的一部分。
关键字:如果用户位于 www.web.dev
并从 static.web.dev
请求图片,则属于同一网站请求。
公共后缀列表定义了哪些网页会被视为位于同一网站上。它不仅依赖于 .com
等顶级域名,还可以包含 github.io
等服务。这样一来,your-project.github.io
和 my-project.github.io
便可算作不同的网站。
关键字:如果用户位于 your-project.github.io
并向 my-project.github.io
请求图片,则属于跨网站请求。
使用 SameSite
属性声明 Cookie 用途
Cookie 上的 SameSite
属性提供了三种不同的方式来控制此行为。您可以选择不指定该属性,也可以使用 Strict
或 Lax
将 cookie 限制为同站点请求。
如果您将 SameSite
设置为 Strict
,则 Cookie 只能在第一方环境中发送;也就是说,Cookie 的网站必须与浏览器地址栏中显示的网站一致。因此,如果 promo_shown
Cookie 设置如下:
Set-Cookie: promo_shown=1; SameSite=Strict
当用户访问您的网站时,系统会按预期随请求一起发送 Cookie。不过,如果用户通过其他网站中的链接进入您的网站,系统不会在该初始请求中发送 Cookie。这对于与始终在初始导航后面显示的功能相关的 Cookie(例如更改密码或进行购买)非常有用,但对于 promo_shown
等 Cookie 来说过于限制。如果您的读者通过该链接访问网站,他们希望系统发送 Cookie,以便应用其偏好设置。
SameSite=Lax
允许浏览器通过这些顶级导航发送 Cookie。例如,如果其他网站引用了您网站的内容(在本例中,是使用您的猫咪照片并提供指向您文章的链接),则会被视为引用了您的内容:
<p>Look at this amazing cat!</p>
<img src="https://blog.example/blog/img/amazing-cat.png" />
<p>Read the <a href="https://blog.example/blog/cat.html">article</a>.</p>
将 Cookie 设置为 Lax
后,如下所示:
Set-Cookie: promo_shown=1; SameSite=Lax
当浏览器为其他人的博客请求 amazing-cat.png
时,您的网站不会发送此 Cookie。不过,当读者点击您网站上指向 cat.html
的链接时,该请求确实会包含 Cookie。
我们建议您以这种方式使用 SameSite
,将影响网站显示的 Cookie 设置为 Lax
,将与用户操作相关的 Cookie 设置为 Strict
。
您还可以将 SameSite
设置为 None
,以指明您希望在所有上下文中发送 Cookie。如果您提供其他网站使用的服务(例如 widget、嵌入内容、联属营销计划、广告或跨多个网站登录),请使用 None
确保您的 intent 清晰明确。
不使用 SameSite 的默认行为变更
浏览器支持
SameSite
属性广受支持,但尚未被广泛采用。过去,在没有 SameSite
的情况下设置 Cookie 时,系统会默认在所有上下文中发送 Cookie,而这会导致用户容易受到 CSRF 和意外信息泄露的影响。为了鼓励开发者声明其意图并为用户提供更安全的体验,IETF 提案“逐步改进 Cookie”列出了两项关键变更:
- 没有
SameSite
属性的 Cookie 被视为SameSite=Lax
。 - 具有
SameSite=None
的 Cookie 还必须指定Secure
,这意味着它们需要安全的上下文。
这两项更改都向后兼容正确实现了旧版 SameSite
属性的浏览器,以及不支持旧版 SameSite
的浏览器。它们旨在通过明确 Cookie 行为和预期用途,减少开发者对浏览器默认行为的依赖。任何不识别 SameSite=None
的客户端都应忽略它。
默认情况下为 SameSite=Lax
如果您在发送某个 Cookie 时未指定其 SameSite
属性,浏览器将将该 Cookie 视为设置为 SameSite=Lax
。不过,我们仍建议明确设置 SameSite=Lax
,以便跨浏览器提供更加一致的用户体验。
SameSite=None
必须是安全的
使用 SameSite=None
创建跨网站 Cookie 时,您还必须将其设为 Secure
,以便浏览器接受这些 Cookie:
Set-Cookie: widget_session=abc123; SameSite=None; Secure
从 Chrome 76 开始,您可以通过启用 about://flags/#cookies-without-same-site-must-be-secure
来测试此行为;从 Firefox 69 开始,您可以在 about:config
中设置 network.cookie.sameSite.noneRequiresSecure
来测试此行为。
此外,我们还建议您尽快将现有 Cookie 更新为 Secure
。
如果您依赖于在您的网站上提供第三方内容的服务,请确保您的服务提供商更新其 Cookie,并更新您网站上的所有代码段或依赖项,以确保网站使用新行为。
SameSite
Cookie 食谱
如需详细了解如何更新 Cookie 以成功处理对 SameSite=None
的这些更改以及浏览器行为差异,请参阅后续文章 SameSite Cookie 食谱。
非常感谢 Lily Chen、Malte Ubl、Mike West、Rob Dodson、Tom Steiner 和 Vivek Sekhar 提供的贡献和反馈。
Cookie 主打图片:Unsplash 上的 Pille-Riin Priske