未在跨域上设置CORS Cookie,使用提取功能,设置了凭据:已设置“包含”和来源

时间:2019-07-10 07:26:50

标签: javascript flask cors cross-domain fetch

我正在使用fetch向后端发出请求。 我使用其他域时未设置Cookie。 当我使用相同的域时,将设置cookie。

为什么未设置?

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

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

*请注意,我测试的前端网址是* {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.....

服务器响应标题

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

2 个答案:

答案 0 :(得分:5)

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

  1. 客户端使用 credentials: 'include' 异步初始化获取请求。有关详情,请参阅 here
  2. 要进行 CORS,服务器响应标头必须包含 Access-Control-Allow-Origin 显式设置为域,可以与服务器域不同。例如,在单页应用架构中,您的前端站点临时托管在 localhost:3000,而您的后端服务器托管在 localhost:8000,则标头应为 Access-Control-Allow-Origin: http://localhost:3000。请参阅 herehere
  3. 为了允许客户端处理 cookie,这显然是一种敏感资源,服务器响应头必须进一步包含 Access-Control-Allow-Credentials: true。见here。请注意,这会强制对 Access-Control-Allow-Origin 进行非通配符设置。参见 here - 这就是为什么在上面的第 2 点中,它必须显式设置为类似 http://localhost:3000 而不是 *
  4. 当服务器设置 cookie 时,它​​必须包含 SameSite=None; Secure; HttpOnly。所以总体来说像Set-Cookie: session_id=12345; SameSite=None; Secure; HttpOnlySameSite 在最新浏览器中似乎是相对new requirement,当 Secure 设置为 SameSite 时,必须与 None 一起使用。
  5. 关于HttpOnly,我还没有找到相关资料,但是在我的实验中,省略它会导致浏览器忽略Set-Cookie标头。
  6. 对后端服务器的进一步请求也必须设置 credentials: 'include'

答案 1 :(得分:1)

  

我只是想通过调用其他域上的服务器来获取当前域的cookie集。

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

您可能会遇到的最接近的情况是,在不同的域中以非Cookie格式返回数据(例如响应的正文),然后使用客户端JS通过{{3}进行存储}。