如何跨源共享 cookie?更具体地说,如何将Set-Cookieheader 与 header 结合使用Access-Control-Allow- Origin?
Set-Cookie
Access-Control-Allow- Origin
下面解释一下我的情况:
我正在尝试为localhost:4000在托管的 Web 应用程序中运行的 API 设置 cookie localhost:3000。
localhost:4000
localhost:3000
看来我在浏览器中收到了正确的响应标头,但不幸的是它们没有效果。这些是响应标头:
HTTP/1.1 200 OK Access-Control-Allow-Origin: http://localhost:3000 Vary: Origin, Accept-Encoding Set-Cookie: token=0d522ba17e130d6d19eb9c25b7ac58387b798639f81ffe75bd449afbc3cc715d6b038e426adeac3316f0511dc7fae3f7; Max-Age=86400; Domain=localhost:4000; Path=/; Expires=Tue, 19 Sep 2017 21:11:36 GMT; HttpOnly Content-Type: application/json; charset=utf-8 Content-Length: 180 ETag: W/"b4-VNrmF4xNeHGeLrGehNZTQNwAaUQ" Date: Mon, 18 Sep 2017 21:11:36 GMT Connection: keep-alive
Response Cookies此外,当我使用 Chrome 开发者工具的网络选项卡检查流量时,我可以看到下面的 cookie 。但是,我看不到在Storage/Cookies. 我没有看到任何 CORS 错误,所以我认为我遗漏了其他内容。
Response Cookies
Storage/Cookies
有什么建议么?
我在 React-Redux 应用程序中使用请求/signin模块向服务器上的端点发出请求。对于我使用快递的服务器。
/signin
快递服务器:
res.cookie('token', 'xxx-xxx-xxx', { maxAge: 86400000, httpOnly: true, domain: 'localhost:3000' })
浏览器中的请求:
request.post({ uri: '/signin', json: { userName: 'userOne', password: '123456'}}, (err, response, body) => { // doing stuff })
我现在疯狂地设置请求和响应标头,确保它们同时出现在请求和响应中。下面是一个截图。注意标题Access-Control-Allow- Credentials、Access-Control-Allow-Headers和。查看我在Axios 的 github 上发现的问题,我的印象是所有必需的标头现在都已设置。然而,还是没有运气…Access- Control-Allow-Methods``Access-Control-Allow- Origin
Access-Control-Allow- Credentials
Access-Control-Allow-Headers
Access- Control-Allow-Methods``Access-Control-Allow- Origin
要允许通过 CORS 请求成功接收和发送 cookie,请执行以下操作。
后端(服务器): 将 HTTP 标头Access-Control-Allow- Credentials值设置为true. 此外,请确保 HTTP 标头Access-Control-Allow-Origin和Access-Control-Allow- Headers已设置,而 不是使用通配符*。
true
Access-Control-Allow-Origin
Access-Control-Allow- Headers
*
有关在 express js 中设置 CORS 的更多信息,请阅读此处的文档。
Cookie 设置: Chrome 和 Firefox 的 Cookie 设置将于 2021 年更新:SameSite=None和Secure. 做的时候SameSite=None,设置Secure是一个要求。请参阅SameSite上的文档和Secure的要求。另请注意,Chrome 开发工具现在改进了网络选项卡和应用程序选项卡中 cookie 问题的过滤和突出显示。
SameSite=None
Secure
前端(客户端): 将XMLHttpRequest.withCredentials标志设置为true,这可以根据使用的请求- 响应库以不同的方式实现:
XMLHttpRequest.withCredentials
jQuery 1.5.1xhrFields: {withCredentials: true}
xhrFields: {withCredentials: true}
ES6 获取() credentials: 'include'
credentials: 'include'
axios :withCredentials: true
withCredentials: true
避免完全做跨站点(CORS)的事情。您可以使用代理来实现这一点。只需使用 DNS(子域)和/或负载平衡将所有流量发送到相同的顶级域名和路由。使用 Nginx,这是相对较少的努力。
这种方法与 JAMStack 完美结合。JAMStack 要求 API 和 Webapp 代码在设计上完全解耦。越来越多的用户阻止了第 3 方 cookie。如果 API 和 Webapp 可以轻松地在同一主机上提供服务,则第 3 方问题(跨站点/CORS)就解决了。在此处或此处阅读有关 JAMStack的信息。
事实证明,如果域包含端口,Chrome 将不会设置cookie。将其设置为localhost(无端口)不是问题。
localhost