Cookie不能在JavaScript(和开发工具)中访问,但与XHR请求一起发送(不使用httponly)(Cookies are not accessible within JavaScript

编程入门 行业动态 更新时间:2024-10-26 20:33:33
Cookie不能在JavaScript(和开发工具)中访问,但与XHR请求一起发送(不使用httponly)(Cookies are not accessible within JavaScript (and the dev tools) but sent along with XHR request (no httponly used))

我使用基于会话的授权在不同域上使用前端和后端应用程序。 我已经建立了一个可用的CORS配置,它在localhost上按预期工作(例如从端口:9000到端口:8080 )。 只要我在安全域上部署应用程序(两个域只允许HTTPS),CSRF cookie就不能在JavaScript中访问,导致前端的错误后续请求(缺少CSRF标头)。

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

我期待cookie被设置并在当前域(前端域)上可见。 我正在使用axios库的withCredentials标志。

你有什么想法,为什么不能从JavaScript或Chrome中的DevTools访问cookie? 这与Strict-Transport-Security标题有什么关系?


1.初始GET响应头

HTTP/1.1 401 Unauthorized
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://[my-frontend-domain]
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Encoding: gzip
Content-Type: application/json;charset=UTF-8
Date: Wed, 20 Sep 2017 11:57:07 GMT
Expires: 0
Pragma: no-cache
Server: Apache-Coyote/1.1
Set-Cookie: CSRF-TOKEN=[some-token]; Path=/
Vary: Origin,Accept-Encoding
X-Content-Type-Options: nosniff
X-Vcap-Request-Id: [some-token]
X-Xss-Protection: 1; mode=block
Content-Length: [some-length]
Strict-Transport-Security: max-age=15768000; includeSubDomains 
  
 

2.后续POST请求标题

POST /api/authentication HTTP/1.1
Host: [my-backend-host]
Connection: keep-alive
Content-Length: [some-length]
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/plain, */*
Origin: [my-frontend-host]
User-Agent: [Google-Chrome-User-Agent]
Content-Type: application/x-www-form-urlencoded
DNT: 1
Referer: [my-frontend-host]
Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,de-CH;q=0.2,it;q=0.2
Cookie: [some-other-cookies]; CSRF-TOKEN=[same-token-as-in-the-previous-request] 
  
 

这个请求应该包含一个CSRF头部,如果cookie可以通过JavaScript访问的话,这个头部会自动添加。

I'm using both a front-end and a back-end application on a different domain with a session-based authorization. I have setup a working CORS configuration, which works as expected on localhost (e.g. from port :9000 to port :8080). As soon as I deploy the applications on secure domains (both domains only allow HTTPS), the CSRF cookie is not accessible anymore within JavaScript, leading to an incorrect follow-up request of the front-end (missing the CSRF header).

The cookie is set by the back-end in the Set-Cookie header without using the HttpOnly flag. It is actually set somewhere in the browser, because the follow-up request contains both the session cookie and the CSRF cookie. Trying to access it by JavaScript (using e.g. document.cookie in the console) returns an empty string. The DevTools of Chrome do not show any cookies on the front-end domain (the back-end domain is not even listed).

I'm expecting the cookie to be set and being visible on the current domain (front-end domain). I'm using the withCredentials flag of the axios library.

Do you have any idea, why the cookie cannot be accessed from JavaScript nor from the DevTools in Chrome? Does this have anything to do with the Strict-Transport-Security header?


Headers

1. Initial GET Response Header

HTTP/1.1 401 Unauthorized
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://[my-frontend-domain]
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Encoding: gzip
Content-Type: application/json;charset=UTF-8
Date: Wed, 20 Sep 2017 11:57:07 GMT
Expires: 0
Pragma: no-cache
Server: Apache-Coyote/1.1
Set-Cookie: CSRF-TOKEN=[some-token]; Path=/
Vary: Origin,Accept-Encoding
X-Content-Type-Options: nosniff
X-Vcap-Request-Id: [some-token]
X-Xss-Protection: 1; mode=block
Content-Length: [some-length]
Strict-Transport-Security: max-age=15768000; includeSubDomains 
  
 

2. Follow-up POST Request Header

POST /api/authentication HTTP/1.1
Host: [my-backend-host]
Connection: keep-alive
Content-Length: [some-length]
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/plain, */*
Origin: [my-frontend-host]
User-Agent: [Google-Chrome-User-Agent]
Content-Type: application/x-www-form-urlencoded
DNT: 1
Referer: [my-frontend-host]
Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,de-CH;q=0.2,it;q=0.2
Cookie: [some-other-cookies]; CSRF-TOKEN=[same-token-as-in-the-previous-request] 
  
 

This request should contain a CSRF header which would automatically be added if the cookie was accessible with JavaScript.

最满意答案

简而言之,不可能访问交叉源cookie, document.cookie只能访问当前( 或父母 )域cookie。

这是其根源的暗示,ssc-hrep3在他的问题中提到了“两个领域”。

从本地部署部署切换到只使用不同端口的后端服务器和前端服务器,到使用两台不同主机的端口时,很容易出现这种错误。 这将在本地工作,因为cookie跨端口共享,并且在使用两个不同的主机时会失败。 (与其他CORS问题不同,这些问题也将在本地公开)

有关更多信息和解决方法,请参阅ssc-hrep3的答案 。

In short, it is not possible to access cross-origin cookies, document.cookie can only access the current (or parent) domain cookies.

The hint for that being the root cause, was ssc-hrep3 mentioning "both domains" in his question.

It's very to easy to make that mistake when switching from a localhost deployment, using only different ports for back-end and front-end servers, to one that uses two different hosts. That will work locally, because cookies are shared across ports, and will fail when two different hosts are used. (Unlike some other CORS issues that will be also exposed locally)

See ssc-hrep3's answer for more information and a workaround.

更多推荐

本文发布于:2023-07-05 15:52:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1039157.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:能在   开发工具   但与   XHR   JavaScript

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!