问题描述
我有一个本地测试应用程序模拟端口 4200 上的主机 test.mywebsite.com
。
它调用 api.test.mywebsite.com
(也是本地托管的)到 /login
请求通过,服务器返回 200 和一些信息,并设置我在响应头中看到的这个头:
Set-Cookie: refreshToken={JWT here}; expires=Sun,23-May-2021 20:38:32 GMT; Max-Age=1296000; path=/; domain=.test.mywebsite.com; HttpOnly
这不会存储在我的浏览器(Chrome 或 Firefox)中,我正在尝试找出原因。
如果需要,这里有一些关于我的设置的更多信息:
Angular 服务器使用 ng serve --host=test.mywebsite.com
在 http://test.mywebsite.com:4200
Kubernetes 后端在 localhost
上运行(我的主机文件将 api.test.mywebsite.com
重定向到 127.0.0.1
),它将请求定向到使用以下代码创建 cookie 的 PHP pod:
setcookie(
"refreshToken",// name
$refreshJWT->token,// token
$refreshJWT->expiration,// expires in 15 days
'/',// path
".".$refreshJWT->domain,// domain
($refreshJWT->environmentType === "test") ? false : true,// security
true // httponly
);
我担心这是一些非常简单的事情,或者是某个地方的疏忽,但我终其一生都无法找出原因。我唯一能想到的就是端口与 cookie 主机不匹配,但据我所知,cookie 域与端口无关。我已经尝试将 :4200
添加到 cookie 域的末尾,但仍然遇到同样的问题。
更新:setcookie() 返回 true,因此在设置标题之前没有输出。
更新 2:我将其部署到临时服务器,尽管没有 DNS 欺骗或代理,但问题仍然存在。
Update3:我已将范围缩小到我的 api 服务器的 Access-Control-Allow-Origin
标头和我的 JS 使用 withCredentials
的组合
我的 Access-Control-Allow-Origin
设置为 *
。如果我将请求 withCredentials
作为 false
发送,它会将正文返回给 JS 但拒绝 cookie。如果我将 withCredentials
设置为 true,它会设置 cookie 但拒绝让 JS 读取正文。
解决方法
它调用 api.test.mywebsite.com
...
domain=.test.mywebsite.com
这些必须是相同的主机名
,我找到了原因,对于任何可能会遇到这个问题的人:
第一个问题是当我的请求通过并返回 200 时,没有设置 cookie,因为我不同意在前端接收 cookie。要在前端同意 cookie,我必须使用 withCredentials。
第二个问题是在后端,我没有明确发送标头 Access-Control-Allow-Credentials 这将允许前端和后端同意 cookie 交换。
第三个问题是我的后端为 Access-Control-Allow-Origin 设置了通配符,如果使用 withCredentials
,我的浏览器需要它与当前主机完全匹配。