CORS Cookie 未在跨域上设置,使用提取,设置凭据:'include' 并且已设置来源

CORS Cookie not set on cross domains, using fetch, set credentials: 'include' and origins have been set

我正在使用 fetch 向后端发出请求。 当我使用不同的域时,cookie 未设置。 当我使用同一个域时设置了 cookie。

为什么没有设置?

我修改了我的 /etc/hosts 文件以使用假名来测试使用相同和不同的域,并确保它们都是 not blacklisted by the browser

如果我对浏览器域和服务器域都使用 local-test-frontend.com 它可以工作,但是如果我将后端 url 更改为 local-test-backend.com 它会失败。

*请注意,我测试的前端 url 是 * http://local-test-frontend.com:3000/login

Javascript

    fetch('http://local-test-backend.com/login',  {
        mode: 'cors',
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(loginRequest),
        credentials: 'include'
    }).then(// Other code here.....

服务器响应Headers

Access-Control-Allow-Credentials    
true
Access-Control-Allow-Origin 
http://local-test-frontend.com:3000
Content-Length  
103
Content-Type    
application/json
Date    
Wed, 10 Jul 2019 07:23:49 GMT
Server  
Werkzeug/0.15.1 Python/3.7.3
Set-Cookie  
MY_TOKEN=a7b8ad50f19…end.com; Path=/; SameSite=Lax

I'm just trying to get a cookie set for my current domain by calling a server on a different domain.

你不能,至少不能直接。 Cookie 属于设置它们的来源。

最接近的是将不同域 return 格式为 non-Cookie 的数据(例如响应的正文),然后使用 client-side JS 来存储它使用 document.cookie.

截至 2021 年 Linux 上的 Edge 90.0.796.0,我设法使用以下方法设置 CORS cookie:

  1. 客户端使用 credentials: 'include' 异步初始化获取请求。有关详细信息,请参阅 here
  2. 要执行 CORS,服务器响应 header 必须包含 Access-Control-Allow-Origin 明确设置为域,可以不同于服务器域。例如,在 Single-Page-App 架构中,您的前端站点临时托管在 localhost:3000,您的后端服务器托管在 localhost:8000,那么 header 应该是 Access-Control-Allow-Origin: http://localhost:3000 .参见 here and here
  3. 为了允许客户端处理 cookie,这显然是一种敏感资源,服务器响应 header 必须进一步包含 Access-Control-Allow-Credentials: true。请参阅 here. Note that this enforces a non-wildcard setting for Access-Control-Allow-Origin. See here - 这就是为什么在上面的第 2 点中,它必须明确设置为 http://localhost:3000 而不是 *
  4. 当服务器设置cookie时,它必须包含SameSite=None; Secure; HttpOnly。所以总体上类似于 Set-Cookie: session_id=12345; SameSite=None; Secure; HttpOnlySameSite 在最新的浏览器中似乎是一个相对的 new requirement,当 SameSite 设置为 None.
  5. 时必须与 Secure 一起使用
  6. 关于HttpOnly,我没有找到相关资料,但在我的实验中,省略它导致浏览器忽略Set-Cookie header。
  7. 对后端服务器的进一步请求也必须设置 credentials: 'include'