【问题标题】:CORS Cookie not set on cross domains, using fetch, set credentials: 'include' and origins have been setCORS Cookie 未在跨域上设置,使用获取,设置凭据:“包含”和来源已设置
【发布时间】:2019-11-19 18:32:15
【问题描述】:

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

为什么没有设置?

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

如果我对浏览器和服务器域都使用local-test-frontend.com,它可以工作,但如果我将后端网址更改为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

【问题讨论】:

  • 你能把你的问题说清楚吗?我没看到这里有什么问题?
  • 通过在地址栏中输入 URL,您可以从 A(从源 X)请求 HTML 文档。这会在响应 B 中给出一个 HTML 文档。然后您使用 JavaScript 向不同的源 (Y) 发出请求 (C),该源 (Y) 得到响应 (D)。其中哪个包含Set-Cookie 标头? (我认为它是 D,但我想确定)。那么,您如何确定 cookie 尚未设置?你会提出额外的要求吗?发源地?
  • 你不能跨域共享 cookie stackoverflow.com/questions/3342140/cross-domain-cookies 虽然
  • @zakir 刚刚添加了“为什么没有设置?”到问题主体。几乎,当向服务器发送请求时,与浏览器的域不同,cookie 不会被浏览器设置
  • @hackerl33t 我不想跨域共享 cookie,我只是想通过调用不同域上的服务器来为我当前的域设置一个 cookie。不确定该链接/答案是否适用?

标签: javascript flask cors cross-domain fetch


【解决方案1】:

我只是想通过调用不同域上的服务器来为我当前的域设置一个 cookie。

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

最接近的可能是让不同的域以非 Cookie 格式(例如响应的正文)返回数据,然后使用客户端 JS 使用 document.cookie 存储它。

【讨论】:

  • 所以如果我的服务器在server.com域上,前端在frontend.com域上,那么frontend.com不可能保存server.com自动发送的cookie?
  • @tt_Gantz — 正确。
  • 同事,对不起...但是可以吗,我看到响应后 Cookie 是由另一个域设置的?远程服务器(跨域请求)回复并设置PHPSSID等苦力(!!!)
【解决方案2】:

截至 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。请参阅here 和here。
  3. 为了让客户端处理显然是敏感资源的cookies,服务器响应头必须进一步包含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; HttpOnly。 SameSite在最新的浏览器中似乎是一个相对的new requirement,当SameSite设置为None时必须和Secure一起使用。
  5. 关于HttpOnly,我没有找到相关资料,但在我的实验中,省略它会导致浏览器忽略Set-Cookie header。
  6. 对后端服务器的进一步请求也必须设置credentials: 'include'。

【讨论】:

  • 这对我帮助很大。使用 Koa 和节点。这就是我所做的。 ctx.cookies.set('SomeKey', token, { sameSite: 'none', secure: true, httpOnly: true });
  • 谢谢伙计,很好的回答!
猜你喜欢
  • 2023-04-04
  • 2015-05-28
  • 2021-08-15
  • 2017-03-30
  • 2017-10-06
  • 2015-12-21
  • 1970-01-01
  • 2016-02-12
  • 2021-12-14
相关资源
最近更新 更多