我在具有基于会话的授权的不同域上同时使用前端和后端应用程序。我已经设置了一个有效的 CORS 配置,它可以按预期工作localhost
(例如从端口:9000
到端口:8080
)。一旦我在安全域上部署应用程序(两个域都只允许 HTTPS),CSRF cookie 就无法再在 JavaScript 中访问,导致前端的后续请求不正确(缺少 CSRF 标头)。
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 访问,则会自动添加该标头。