SameSite Cookie 配方

<ph type="x-smartling-placeholder">

Chrome FirefoxEdge、 和其他网站都根据 IETF 的规定更改默认行为。 提案 提升 Cookie 效果 以便:

  • 没有 SameSite 属性的 Cookie 会被视为 SameSite=Lax, 这意味着默认行为是仅限第一方使用 Cookie 上下文。
  • 用于跨网站使用的 Cookie 必须SameSite=None; Secure 指定为 使其能够纳入第三方环境中。

如果您还没有更新属性,则应更新 Cookie,以免在将来遭到拦截。

浏览器支持

  • Chrome:51。 <ph type="x-smartling-placeholder">
  • Edge:16。 <ph type="x-smartling-placeholder">
  • Firefox:60。 <ph type="x-smartling-placeholder">
  • Safari:13. <ph type="x-smartling-placeholder">

来源

跨网站或第三方 Cookie 的使用场景

在一些常见使用场景和模式中,都需要使用 Cookie 在第三方环境中发送的信息。如果您提供或依赖其中某种用途 请确保您或提供商的 Cookie 更新正常, 以确保服务正常运行

<iframe> 中的内容

<iframe> 中显示的来自其他网站的内容属于第三方 上下文。标准用例包括:

  • 从其他网站共享的嵌入内容,例如视频、地图、代码示例 和社交帖子。
  • 来自外部服务(例如付款、日历、预订和 预留功能
  • 创造不太明显的社交按钮或防欺诈服务等微件 <iframes>

例如,Cookie 可用于维护会话状态、存储 常规偏好设置、启用统计信息或针对具有 现有账号

<ph type="x-smartling-placeholder">
</ph> 所嵌入内容的网址与网页的网址不匹配的浏览器窗口的示意图。 <ph type="x-smartling-placeholder">
</ph> 如果嵌入的内容与顶级网站并非来自同一个网站 而是第三方内容。

由于网页本身就是可组合的,因此 <iframes> 也用于嵌入 在顶级或第一方环境中浏览的内容。网站的任何 Cookie iframe 中显示的网站将被视为第三方 Cookie。如果您 创建您希望其他网站嵌入的网站,并且需要使用 Cookie 您还需要确保这些链接已标记为跨网站使用 可以在没有它们的情况下优雅回退

“不安全”跨网站请求

“不安全”这里可能听起来不太令人担忧 想要改变状态在网络上,这主要是 POST 请求。饼干 标记为 SameSite=Lax 的 SDK 将在安全的顶级导航期间发送,例如点击 链接以转到其他网站。但是,像 <form> 提交内容到 使用 POST 的其他网站不包含 Cookie。

<ph type="x-smartling-placeholder">
</ph> 请求从一个页面移动到另一个页面的示意图。 <ph type="x-smartling-placeholder">
</ph> 如果传入请求使用“safe”方法,网页会发送 Cookie。

此格式用于可将用户重定向到远程 服务执行某种操作后返回,例如重定向到 第三方身份提供方在用户离开网站之前 包含单一用途令牌的集合,且该令牌 检查返回请求,以减少 跨站请求伪造 (CSRF) 攻击。如果返回请求是通过 POST 发送的,您需要将 设为 SameSite=None; Secure

远程资源

网页上的任何远程资源,例如来自 <img> 标记或 <script> 标记的资源; 可能依赖于随请求一起发送的 Cookie。常见用例包括 跟踪像素和个性化内容。

这也适用于使用 fetchXMLHttpRequest。如果使用fetch() credentials: 'include' 个选项, 这些请求都可能包含 Cookie 对于 XMLHttpRequest,预期的 Cookie 通常由 withCredentials 适用于 true。这些 Cookie 必须经过适当标记 跨网站请求

WebView 中的内容

平台专用应用中的 WebView 由浏览器提供支持。开发者需要 测试影响用户应用的限制或问题是否也适用于 其应用的 WebView

Android 还允许其平台专用应用直接使用 CookieManager API。 与使用标头或 JavaScript 设置的 Cookie 一样,您也可以考虑 SameSite=None; Secure(如果需要跨网站使用)。

立即如何实现 SameSite

将仅在第一方环境中需要的任何 Cookie 标记为 SameSite=LaxSameSite=Strict,具体视您的需求而定。如果您没有标记这些 Cookie 而是依靠默认浏览器行为来处理它们 不一致,并且可能会针对每种浏览器 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 和更新的默认行为仍然存在 相对较新的,不同的浏览器会以不同的方式处理它们。您可以推荐 访问 chromium.org 上的“更新”页面 了解已知问题列表,但此列表可能并不详尽。

一种可能的解决方法是将每个 Cookie 同时设置为新样式和旧样式:

Set-cookie: 3pcookie=value; SameSite=None; Secure
Set-cookie: 3pcookie-legacy=value; Secure

实现较新行为的浏览器会使用 SameSite 设置 Cookie 值。未实现新行为的浏览器会忽略该值并将 3pcookie-legacy Cookie。在处理包含的 Cookie 时,您的网站应 首先检查是否存在新样式的 Cookie,然后回退到 如果无法找到新的 Cookie,则会使用旧版 Cookie。

以下示例展示了如何使用 Express 框架及其 cookie-parser 中间件:

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 标头。请参阅 不兼容客户端列表 并使用适合您平台的用户代理检测库 ua-parser-js 库 。此方法只需要您进行一项更改 嗅探功能可能无法捕捉到所有受影响的用户。

在语言、库和框架中支持 SameSite=None

大多数语言和库都支持 SameSite 属性, Cookie。不过,由于添加 SameSite=None 仍然是相对容易的, 近期,您可能需要暂时解决一些标准行为。 这些行为记录在 GitHub 上的 SameSite 示例代码库

获取帮助

Cookie 在网络上无处不在,开发团队很少使用 全面了解其网站的设置并使用它们,尤其是 在跨网站用例中的应用当您遇到问题时,可能是 是否有人遇到过这个问题,请随时与我们联系: