Chrome,Firefox,Edge和其他浏览器将根据IETF提案Incrementally Better Cookies更改其默认行为,以便:
- 没有
SameSite
属性的cookie将被视为SameSite=Lax
,这意味着默认行为是将cookie仅限于第一方上下文。 - 跨站点使用的Cookie必须指定
SameSite=None
; 确保将其包含在第三方上下文中。
这将成为Chrome 80的默认行为,Chrome 80将于2019年12月19日发布Beta版,并计划于2020年2月发布稳定版。如果您当前提供用于跨站点使用的Cookie,您需要在该日期之前进行更改以支持新的默认设置。
跨浏览器支持
请参阅MDN的Set-Cookie
页面的Browser compatibility部分。
跨站点或第三方Cookie的用例
在许多常见的用例和模式中,需要在第三方上下文中发送cookie。如果您提供或依赖这些用例之一,请确保您或提供者正在更新其cookie,以确保服务继续正常运行。
<iframe>中的内容
<iframe>
中显示的来自其他站点的内容是在第三方上下文中。这里的标准用例是:
- 从其他站点共享的嵌入式内容,例如视频,地图,代码示例和社交帖子。
- 来自外部服务的小部件,例如付款,日历,预订和预订功能。
- 诸如社交按钮或反欺诈服务之类的小部件会创建不太明显的
<iframes>
。
Cookies在这里可以用于维护会话状态,存储常规首选项,启用统计信息或为具有现有帐户的用户个性化内容。

如果嵌入的内容与顶级浏览上下文不在同一个站点,则为第三方内容。
此外,由于Web具有固有的可组合性,因此<iframes>
用于嵌入也在top-level或第一方上下文中查看的内容。 当网站显示在frame中时,该网站使用的任何cookie都将被视为第三方cookie。 如果您要创建要由其他人轻松嵌入的站点,同时还依赖Cookie起作用,则还需要确保已将这些站点标记为跨站点使用,或者可以在没有它们的情况下优雅地回退。
跨站点的“不安全”请求
尽管“不安全”在这里听起来可能有点儿涉及,但这是指可能旨在更改状态的任何请求。 在网络上主要是POST请求。标记为SameSite=Lax
的Cookie将在安全的top-level导航中发送,例如 点击链接以转到其他站点。但是,通过POST通过<form>
提交到其他站点之类的内容将不包含cookie。

如果传入请求使用“安全”方法,则将发送cookie
此模式用于可能会将用户重定向到远程服务以在返回之前执行某些操作的站点,例如,重定向到第三方标识提供程序。 在用户离开站点之前,将设置一个cookie,其中包含一个一次性使用令牌,并期望可以在返回的请求上检查此令牌以减轻跨站点请求伪造(CSRF)攻击。 如果返回请求是通过POST发出的,则有必要将Cookie标记为SameSite=None; Secure
。
远程资源
页面上的任何远程资源都可能依赖来自<img>
标记,<script>
标记等的Cookie来与请求一起发送。常见的用例包括跟踪像素和个性化内容。
这也适用于通过fetch
或XMLHttpRequest
从JavaScript发起的请求。如果使用 credentials: 'include'
option调用fetch()
,则很好地表明在这些请求上可能会期望使用cookie。对于XMLHttpRequest,您应该查找withCredentials属性设置为true
的实例。这很好地表明,可能会在这些请求上出现cookie。这些cookie将需要适当地标记为包含在跨站点请求中。
WebView中的内容
本机应用程序中的WebView由浏览器提供动力,您将需要测试是否存在相同的限制或问题。在Android中,如果WebView由Chrome驱动,则新的默认值将不会立即应用于Chrome 80。但是,其目的是将来应用它们,因此,您仍然应该为此进行测试并为此做准备。此外,Android允许本机应用直接通过 CookieManager API设置Cookie。与通过headers或JavaScript设置的Cookie一样,请考虑包含SameSite=None; Secure
,如果打算用于跨站点使用,请确保安全。
目前如何实施SameSite
对于仅在第一方上下文中需要它们的cookie,理想情况下,应根据需要将它们标记为SameSite=Lax
或SameSite=Strict
。 您还可以选择不执行任何操作,仅允许浏览器强制执行其默认设置,但这会带来跨浏览器行为不一致以及每个cookie可能出现控制台警告的风险。
Set-Cookie: first_party_var=value; SameSite=Lax
对于第三方上下文中所需的Cookie,您需要确保将其标记为SameSite=None; Secure
。 请注意,您需要同时使用这两个属性。 如果您仅指定None
而无Secure
,则cookie将被拒绝。但是,浏览器的实现之间存在一些互不兼容的差异,因此您可能需要使用下面处理不兼容的客户端中描述的一些缓解策略。
Set-Cookie: third_party_var=value; SameSite=None; Secure
处理不兼容的客户端
由于这些更改(包括None
)和更新默认行为仍然相对较新,因此浏览器之间就如何处理这些更改存在不一致之处。 您可以参考updates page on chromium.org以了解当前已知的问题,但是无法确定是否详尽无遗。 尽管这不是理想的选择,但可以在此过渡阶段中采用一些解决方法。不过,一般规则是将不兼容的客户端视为特例。不要为实施较新规则的浏览器创建例外。
第一种选择是同时设置新样式和旧样式的cookie:
Set-cookie: 3pcookie=value; SameSite=None; Secure Set-cookie: 3pcookie-legacy=value; Secure
实现较新行为的浏览器将使用SameSite
值设置cookie,而其他浏览器可能会忽略或错误地设置它。 但是,那些相同的浏览器将设置3pcookie-legacy cookie
。 在处理包含的cookie时,站点应首先检查是否存在新的cookie(如果找不到),然后回退到旧的cookie。
下面的示例演示如何使用 Express framework及其cookie-parser中间件在Node.js中执行此操作。
const express = require('express'); const cp = require('cookie-parser'); const app = express(); app.use(cp()); app.get('/set', (req, res) => { // Set the new style cookie res.cookie('3pcookie', 'value', { sameSite: 'none', secure: true }); // And set the same value in the legacy cookie res.cookie('3pcookie-legacy', 'value', { secure: true }); res.end(); }); app.get('/', (req, res) => { let cookieVal = null; if (req.cookies['3pcookie']) { // check the new style cookie first cookieVal = req.cookies['3pcookie']; } else if (req.cookies['3pcookie-legacy']) { // otherwise fall back to the legacy cookie cookieVal = req.cookies['3pcookie-legacy']; } res.end(); }); app.listen(process.env.PORT);
不利之处在于,这涉及设置冗余cookie以覆盖所有浏览器,并且需要在设置和读取cookie时进行更改。但是,此方法应涵盖所有浏览器,无论其行为如何,并确保第三方cookie仍能像以前一样运行。
或者,在发送Set-Cookie
标头时,您可以选择通过用户代理字符串检测客户端。请参阅 list of incompatible clients,然后为您的平台使用适当的库,例如Node.js上的 ua-parser-js库。建议您找到一个库来处理用户代理检测,因为您很可能不想自己编写这些正则表达式。
这种方法的好处在于,它只需要在设置cookie时进行一次更改即可。 但是,此处的必要警告是用户代理嗅探本身是脆弱的,可能无法捕获所有受影响的用户。
无论选择哪种选项,建议您都确保有一种记录通过旧route的流量levels的方法。一旦这些levels下降到网站可接受的阈值以下,请确保您有提醒或警报以删除此替代方法。
语言,库和框架中对SameSite=None
的支持
大多数语言和库都支持cookie的SameSite
属性,但是SameSite=None
的添加仍然相对较新,这意味着您可能现在需要解决一些标准行为。 这些都记录在SameSite
examples repo on GitHub.。
获得帮助
Cookies到处都是,很少有网站能够完全审核它们的设置和使用位置,尤其是当您将跨站点用例投入使用后。 当您遇到问题时,这很可能是任何人第一次遇到该问题-因此,请随时与我们联系:
- Raise an issue on the
SameSite
examples repo on GitHub. - Post a question on the “samesite” tag on StackOverflow.
- For issues with Chromium’s behavior, raise a bug via the [SameSite cookies] issue template.
- Follow Chrome’s progress on the
SameSite
updates page.