Cookie在JavaScript(和开发工具)中不可访问,但与XHR请求一起发送(不使用httponly)

Cookie在JavaScript(和开发工具)中不可访问,但与XHR请求一起发送(不使用httponly),javascript,cookies,cross-domain,hsts,strict-transport-security,Javascript,Cookies,Cross Domain,Hsts,Strict Transport Security,我在另一个域上使用基于会话的授权的前端和后端应用程序。我已经设置了一个工作的CORS配置,该配置在本地主机上按预期工作(例如从端口:9000到端口:8080)。一旦我将应用程序部署到安全域上(两个域都只允许HTTPS),JavaScript中就无法再访问CSRF cookie,从而导致前端的后续请求不正确(缺少CSRF头) cookie由后端使用HttpOnly标志在set cookie头中设置,而不使用HttpOnly标志。它实际上设置在浏览器中的某个位置,因为后续请求同时包含会话cookie

我在另一个域上使用基于会话的授权的前端和后端应用程序。我已经设置了一个工作的CORS配置,该配置在
本地主机上按预期工作(例如从端口
:9000
到端口
:8080
)。一旦我将应用程序部署到安全域上(两个域都只允许HTTPS),JavaScript中就无法再访问CSRF cookie,从而导致前端的后续请求不正确(缺少CSRF头)

cookie由后端使用
HttpOnly
标志在
set cookie
中设置,而不使用
HttpOnly
标志。它实际上设置在浏览器中的某个位置,因为后续请求同时包含会话cookie和CSRF cookie。试图通过JavaScript访问它(例如在控制台中使用
document.cookie
)返回一个空字符串。Chrome的DevTools在前端域上不显示任何cookie(后端域甚至没有列出)

我希望cookie被设置并在当前域(前端域)上可见。我正在使用库的
with credentials
标志

您知道为什么不能从JavaScript或Chrome中的DevTools访问cookie吗?这是否与
严格的传输安全性
标题有关


标题 一,。初始获取响应头

HTTP/1.1 401未经授权
访问控制允许凭据:true
访问控制允许来源:https://[我的前端域]
缓存控制:无缓存,无存储,最大年龄=0,必须重新验证
内容编码:gzip
内容类型:application/json;字符集=UTF-8
日期:2017年9月20日星期三11:57:07 GMT
过期日期:0
Pragma:没有缓存
服务器:ApacheCoote/1.1
设置Cookie:CSRF-TOKEN=[some TOKEN];路径=/
改变:来源,接受编码
X-Content-Type-Options:nosniff
X-Vcap-Request-Id:[某个令牌]
X-Xss-Protection:1;模式=块
内容长度:[部分长度]
严格的交通安全:最大年龄=15768000;includeSubDomains
正如您所看到的,XHR规范明确禁止读取集Cookie。最好的方法是在头中传递信息,而不是cookie

一, 您可能需要添加标头以允许传递特定标头

出于测试目的,请尝试将以下内容添加到服务器响应标题(选项方法)中

Access-Control-Allow-Headers: Content-Type, *
在生产中,我建议如下限制标题(但我不能100%确定标题列表是否正确,如果有效,需要在这里进行试验)

请参见此以获取参考

2. 您可能遇到的另一个问题是,cookie将设置在后端服务所在的域上(而不是您查询的域上)

请检查一下这个

3. 作为最后一个问题的选项-浏览器可以禁止从
a.xxx.com


在这种情况下,您可以尝试在父域
xxx.com
上设置cookie,这样您的客户端就可以使用cookie了;DR
:无法对跨域cookie进行读取访问。将CSRF令牌添加到响应头将是一个解决方案。另一个完全绕过CORS和跨域请求的解决方案是使用反向代理


问题 正如我在上面的问题中所说,JavaScript是我前端的一部分(例如
https://example1.com
正在尝试从我的后端访问非
HttpOnly
cookie,例如
https://example2.com
。为了能够使用JavaScript访问远程API,我使用CORS。这允许请求通过。我在前端使用
和凭据:true
访问控制trol Allow Credentials:true
位于后端。然后,
Set Cookie
头将Cookie设置在后端原点,而不是前端原点。因此,Cookie在DevTools中或JavaScript中的
document.Cookie
命令中都不可见

设置在后端源上的cookie始终是通过CORS发送到后端的请求的一部分。但是,我需要访问CSRF cookie的内容,才能将令牌添加到请求头中(以防止CSRF攻击)。我发现,无法读取(或写入)使用JavaScript来自不同域的cookie–无论使用何种CORS设置(请参见这些StackOverflow答案:,)。浏览器将对cookie内容的访问限制在相同域源

解决 由此得出结论,不可能访问不同域的非HttpOnly
cookie的内容。解决此问题的方法是将CSRF令牌设置为附加的自定义响应标头。这些标头通常也不能被其他域访问。但是,这些标头可以通过后端的CORS设置
Access Control Expose Headers
。只要使用严格限制的
Access Control Allow Origin
头,这是安全的

另一个解决方法是使用反向代理,它完全可以避免COR和跨域请求的问题。使用这种反向代理在前端提供一个特殊路径,该路径将重定向到后端(服务器端)。例如,调用
https://front-end/api
被代理到
https://back-end/api
。由于来自前端的所有请求都是向同一域上的前端代理发出的,因此浏览器将每个调用视为同一域请求,并且Cookie直接设置在前端源上。此解决方案的缺点包括:由于另一台服务器处于中间(延迟)而导致的整体性能问题,需要在两个来源上设置cookie(直接访问后端时登录两次)。Se
Access-Control-Allow-Headers: Cookie, Set-Cookie