Set-Cookie 标头无法跨域工作

Posted

技术标签:

【中文标题】Set-Cookie 标头无法跨域工作【英文标题】:Set-Cookie header not working across domain 【发布时间】:2020-06-29 17:58:49 【问题描述】:

我在一个网站上https://aaa.shared.com。该网站(称为A)向url https://zzz.shared.com/some/path(网站Z)发送xhr 请求,并收到带有以下标头的响应:

access-control-allow-credentials: true
access-control-allow-origin: aaa.shared.com
set-cookie: foo=bar; expires=Fri, 01 Jan 2100 00:00:00 GMT; path=/; secure; samesite=none; httponly

(我关注answer on this question添加access-control标头)

现在,我期望的是,无论何时我在 A 或 Z 上,每当请求到达 到 Z (跨域或同源,重要的是请求的 URL)浏览器会添加 cookie,但它不会!此外,我看不到它在浏览器开发工具(F12 -> 应用程序 -> Cookies)中设置。我正在使用 Chrome,但目标是跨浏览器解决方案。

我错过了什么?我发现很难找到有关Set-Cookie 标头在请求不同来源时如何工作的详细信息。

编辑:rowan_z 最初建议将 samesite=lax 替换为 samesite=none,因为此问题的第一个版本中的 A 和 Z 是完全独立的域(仅共享 .com 部分)。我试过了,但没有帮助。但是现在我意识到它们实际上被视为SameSite,因为它们位于shared.com域的不同子域上。所以现在我相信samesite=lax 也应该在这里工作。

更新: 最后,我只是将应用程序aaa.shared.com 移动到具有某些路径zzz.shared.com/aaa/path 的同一子域下,因为处理cookie 和CORS 非常困难。此外,将其配置为使用 localhost 会增加额外的复杂性。

【问题讨论】:

将 cookie 的域设置为“shared.com”,如下所述:***.com/a/60730433/4448410 您根本没有设置域属性,因此默认情况下它可能设置为“aaa.shared” .com” 【参考方案1】:

您所做的所有事情确实是必需才能使其发挥作用:

access-control-allow-credentials: true access-control-allow-origin: aaa.shared.com(不是通配符) Secure SameSite=None

您在发送请求时只是遗漏了一件事:credentials: 'include'。

我创建了一个模拟端点,您可以使用它来测试这行代码两次(在另一个域的控制台中):

fetch('https://***.free.beeceptor.com',  credentials: 'include' );

您会注意到 cookie 将被第二次发送。

如果模拟端点过期(不知道它会持续多久),或者如果有人破坏它,您可以在标头配置中使用此 JSON 在 http://beeceptor.com 上重新创建它:


    "Content-Type": "application/json",
    "Set-Cookie": "test=value; Path=/; Secure; SameSite=None;",
    "access-control-allow-origin": "https://yourdomain",
    "Access-Control-Allow-Credentials": "true"

【讨论】:

谢谢。我自己必须弄清楚的另一点是,在这种情况下,浏览器实际上发送了OPTIONS 请求GET(我认为这是因为我们要求提供凭据)。 Chrome 最近在开发工具中不再显示 OPTIONS 请求,所以我得到的错误有点误导,因为它似乎在抱怨 GET 响应,而实际上它在抱怨 OPTIONS 请求。意识到这一点,我刚刚在this SO answer 之后重新启用了OPTIONS 请求跟踪 是的,OPTIONS 是因为 cookie 使请求“不简单”(这是 HTTP 规范中的一个术语),并触发了预检请求以检查端点是否真的接受了我们的请求即将发送。这在这里解释得很清楚:developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests【参考方案2】:

您已明确声明 SameSite=Lax 限制跨站点请求发送 cookie。这看起来像是您希望 SameSite=None 允许这些 cookie 的情况。

更多详情:https://web.dev/samesite-cookies-explained

【讨论】:

嗨,谢谢,好地方。我在您的精彩文章中添加了samesite=none。不幸的是,它似乎并没有为我解决问题。 cookie 仍未设置且未发送 任何想法在这里可能会发生什么将不胜感激 其实这可能更有趣,我已经更新了问题。我的域 A 和域 Z 可能是 SameSite,因为看起来像 xxx.sss.comyyy.sss.com(它们是同一个 sss.com 域`的子域)

以上是关于Set-Cookie 标头无法跨域工作的主要内容,如果未能解决你的问题,请参考以下文章

跨域 POST 请求的 CSRF 验证在生产中失败

标头无法使用跨域传入 ajax

Set-Cookie后,Cookie丢失问题解决(跨域)

无法从前端 JavaScript 访问跨域响应标头

Web Api 跨域基础认证

axios 跨域和请求自动set cookie