SameSite Cookie 说明

Browser Support

  • Chrome: 51.
  • Edge: 16.
  • Firefox: 60.
  • Safari: 13.

每个 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。如果您提供的服务会被其他网站使用,例如微件、嵌入式内容、联属营销计划、广告或跨多个网站登录,请使用 None 确保您的意图清晰。

三个 Cookie,根据其上下文分别标记为“None”“Lax”或“Strict”
将 Cookie 的上下文明确标记为 None、Lax 或 Strict。

未指定 SameSite 属性时的默认行为变更

Browser Support

  • Chrome: 80.
  • Edge: 86.
  • Firefox: behind a flag.
  • Safari: not supported.

SameSite 属性得到了广泛支持,但尚未被广泛采用。 过去,在未设置 SameSite 的情况下,默认会在所有上下文中发送 Cookie,这会使用户容易受到 CSRF 和意外信息泄露的影响。为了鼓励开发者声明其意图并为用户提供更安全的体验,IETF 提案逐步改进 Cookie 提出了两项关键变更:

  • 没有 SameSite 属性的 Cookie 被视为 SameSite=Lax。
  • 具有 SameSite=None 的 Cookie 还必须指定 Secure,这意味着它们需要安全上下文。

这两项变更都向后兼容已正确实现先前版本 SameSite 属性的浏览器,以及不支持早期 SameSite 版本的浏览器。这些变更旨在通过明确 Cookie 行为和预期用途,减少开发者对浏览器默认行为的依赖。任何无法识别 SameSite=None 的客户端都应忽略它。

默认情况下为 SameSite=Lax

如果您在发送 Cookie 时未指定其 SameSite 属性,浏览器会将其视为设置为 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,并更新您网站上的所有代码段或依赖项,以确保其使用新行为。

如需详细了解如何更新 Cookie 以成功应对 SameSite=None 的这些变化以及浏览器行为的差异,请参阅后续文章 SameSite Cookie 方案。

衷心感谢 Lily Chen、Malte Ubl、Mike West、Rob Dodson、Tom Steiner 和 Vivek Sekhar 的贡献和反馈。