我正在尝试从托管我的 api 服务器的整体架构并将 SPA 反应为单独的托管选项(在同一域上,只是不同的子域)。
我的前端托管在 app.domain.com 上,后端托管在 api.domain.com 上(例如)。
我的服务器的 Set-Cookie 标头构造如下:
Set-Cookie: cookieName=value; Path=/; Secure; HttpOnly; Domain=.domain.com; SameSite=None
API 响应成功,并且在 Chrome 网络选项卡中识别了 cookie(在 net 网络选项卡中单击请求,然后单击 cookie 选项卡,我看到它很好地解析出来了)。
但是,Cookie 不会存储在应用程序选项卡中(Cookie 存储),也不会通过浏览器获取 API 在后续 API 请求中发送。这导致我的 React SPA 由于缺少会话而在所有后续 API 请求上收到 401。
此外,没有控制台警告报告被阻止或无效的 cookie...但是,如果我使用以下命令启动 chrome,则 cookie 的存储不会出现问题,并且 React SPA 可以获取会话令牌:
open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
这表明它与安全相关......但是我不明白如何。这些不是第 3 方 cookie,因为域是相同的(只是不同的子域)。 HTTPS 流量是根据
secure
cookie 要求使用的...并且我正在使用前面的“.”设置 cookie 域。表明我跨子域共享访问的意图。
我正在使用 Chrome 版本 124.0.6367.91(官方版本)(64 位)进行测试
*请注意:我使用“域”仅用于示例目的 - 实际上我使用的是真实的域。还应该注意的是,所有 API 流量均通过 HTTPS。
我在 cookie 上尝试过没有 SameSite 属性。我尝试调整我的 cookie 设置以允许第 3 方 cookie(没有区别)。我已经尝试了 Firefox 和 Chrome 的新会话 (ingonito),但 cookie 仍然被完全忽略。
我希望,由于我的 cookie 是由具有相同域(只是不同子域)的服务器设置的,因此它会被视为第一方并随每个请求一起发送。
HttpOnly cookie 属性也是有意为之;我不希望 JS 可以访问会话令牌(用于 XSS 保护);我只是希望它随每个请求一起发送到我的后端 api.domain.com。事实上,我的服务器将 cookie 域设置为 .domain.com(注意前面的点)应该使 cookie 适用于所有子域。,
如果通过 HTTP 加载的页面发出 HTTPS 请求,则即使两个请求都使用公共超级域,这也会被视为跨站点请求。这是因为在确定
site时会考虑架构(
http:
或 https:
)。
因此,浏览器可能会阻止响应该跨站点请求而收到的 Cookie,因为它们是第三方 Cookie。这要么是因为浏览器设置,要么是因为浏览器供应商试图阻止第三方 cookie。
您可以通过访问 http://httpbin.org/html,打开浏览器控制台并执行来验证这一点
fetch("https://httpbin.org/response-headers?Set-Cookie=a=b;Secure;SameSite=None;HttpOnly",
{credentials: "include"})