fetch 在本地设置同源 cookie,但相同的代码在部署时不会设置 cookie

问题描述 投票:0回答:1

我正在撕扯我的头发。请帮忙!我有一个用户界面 SPA 应用程序,它是身份应用程序的前端。该应用程序有一个登录 API,用于设置身份验证 cookie。 SPA 使用具有

fetch
credentials: "same-origin"
函数将登录凭据发布到此登录 API 端点,因为它期望包含会话 cookie 的响应上有
Set-Cookie
标头。然后,它将浏览器重定向到与 API 位于同一域的回调端点,该 API 需要请求中的会话 cookie。

当我在本地运行它时,它按预期工作,这是跟踪:

  1. 登录API请求:
POST https://identity.mywebsite.local:44119/auth/email HTTP/1.1
Host: identity.mywebsite.local:44119
Connection: keep-alive
Content-Length: 39
sec-ch-ua: "Microsoft Edge";v="123", "Not:A-Brand";v="8", "Chromium";v="123"
sec-ch-ua-platform: "Windows"
DNT: 1
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0
Content-Type: application/x-www-form-urlencoded
Accept: */*
Origin: http://my.mywebsite.local:3100
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://my.mywebsite.local:3100/
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-GB,en;q=0.9

[email protected]&password=mypassword
  1. 登录 API 响应(注意正在设置的
    mywebsite-identity
    cookie):
HTTP/1.1 200 OK
Content-Length: 0
Date: Fri, 26 Apr 2024 11:00:50 GMT
Server: Kestrel
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://my.mywebsite.local:3100
Cache-Control: no-cache,no-store
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Pragma: no-cache
Set-Cookie: mywebsite-session=1F13A118FA46BD80ED830D1AFEBDAA0D; path=/; secure; samesite=none
Set-Cookie: mywebsite-identity=[value]; expires=Fri, 10 May 2024 11:00:51 GMT; path=/; secure; samesite=none; httponly
R-Source: identity
  1. 回调请求(注意发送的
    mywebsite-identity
    cookie):
GET https://identity.mywebsite.local:44119/connect/authorize/callback?client_id=www&... HTTP/1.1
Host: identity.mywebsite.local:44119
Connection: keep-alive
sec-ch-ua: "Microsoft Edge";v="123", "Not:A-Brand";v="8", "Chromium";v="123"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
DNT: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://my.mywebsite.local:3100/
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-GB,en;q=0.9
Cookie: mywebsite-session=1F13A118FA46BD80ED830D1AFEBDAA0D; mywebsite-identity=[value]

但是当我将这段确切的代码部署到远程环境时,浏览器不再设置 API 响应中收到的 cookie。这是痕迹:

  1. 登录API请求:
POST https://identity-build.mywebsite.org.uk/auth/email HTTP/1.1
Host: identity-build.mywebsite.org.uk
Connection: keep-alive
Content-Length: 50
sec-ch-ua: "Microsoft Edge";v="123", "Not:A-Brand";v="8", "Chromium";v="123"
sec-ch-ua-platform: "Android"
DNT: 1
sec-ch-ua-mobile: ?1
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Mobile Safari/537.36 Edg/123.0.0.0
Content-Type: application/x-www-form-urlencoded
Accept: */*
Origin: https://my-build.mywebsite.org.uk
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://my-build.mywebsite.org.uk/
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-GB,en;q=0.9

[email protected]&password=mypassword1
  1. 登录 API 响应(请注意
    mywebsite-identity
    cookie 按预期设置):
HTTP/1.1 200 OK
Date: Fri, 26 Apr 2024 11:03:00 GMT
Content-Length: 0
Connection: keep-alive
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://my-build.mywebsite.org.uk
Cache-Control: no-cache,no-store
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Pragma: no-cache
Set-Cookie: mywebsite-session=1C5F6777E03D96BD215029199901B927; path=/; samesite=none
Set-Cookie: mywebsite-identity=[value]; expires=Fri, 10 May 2024 11:03:00 GMT; path=/; samesite=none; httponly
Request-Context: appId=cid-v1:fff610af-e464-4fb4-8ece-c73f6587e07b
R-Source: identity
CF-Cache-Status: DYNAMIC
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=WHaIgYERtzjcCm5robKrgl0nLh0XZSHWmaPoU48%2B5MTDDWgVXSs9MO%2Fqe2q4lgutPrR6HdSEAfFbNlh42Xmzw0AEU2TqIlEbynCNJVt4Qkd7VZ3TxVLfM2kjxut6br84jgUmYR2C9HjFj0RaG5"}],"group":"cf-nel","max_age":604800}
NEL: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
Server: cloudflare
CF-RAY: 87a6156f2b3071e1-LHR
alt-svc: h3=":443"; ma=86400
  1. 回调请求(注意没有发送cookie,因为浏览器没有从之前的响应中设置它们):
GET https://identity-build.mywebsite.org.uk/connect/authorize/callback?client_id=www&... HTTP/1.1
Host: identity-build.mywebsite.org.uk
Connection: keep-alive
Upgrade-Insecure-Requests: 1
DNT: 1
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Mobile Safari/537.36 Edg/123.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
sec-ch-ua: "Microsoft Edge";v="123", "Not:A-Brand";v="8", "Chromium";v="123"
sec-ch-ua-mobile: ?1
sec-ch-ua-platform: "Android"
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-GB,en;q=0.9

我看不出有什么不同足以产生这种影响。

如果它有用,SPA 是一个 nextjs 应用程序(其中 API 调用是客户端),并且获取代码如下所示:

fetch(url, {
  method: "POST",
  credentials: "same-origin",
  headers:{
    'Content-Type': 'application/x-www-form-urlencoded'
  },    
  body: formData
})

我应该提到,虽然 API 运行在

identity-build.mywebsite.org.uk
上(这也是我希望设置 cookie 的域),但调用它的 SPA 运行在
my-build.mywebsite.org.uk
上。我的假设是我们在这里关心的起源(就浏览器 cookie 安全性而言)是 API 的域。

javascript cookies fetch-api credentials
1个回答
0
投票

在您的开发配置中,会在

secure
响应标头中发送
Set-Cookie
标志,而在构建配置中,不包含
secure
标志。在开发和构建配置中,
Set-Cookie
标头都包含
samesite=none
标志。如果设置了
samesite=none
,则必须包含
secure
标志,否则 cookie 将被阻止。请参阅 MDN 文档上的Set-Cookie

要解决此问题,请确保您使用有效的 HTTPS 配置并编辑响应标头以确保

Set-Cookie
包含
secure
标志。

或者,由于站点是同一域的子域,因此该请求不被视为跨域,因此不需要包含

samesite=none
标志来在请求中发送 cookie。删除
samesite=none
标志可以解决问题并降低 CSRF 的风险。

奇怪的是,API 在 dev 中发送了有效的

Set-Cookie
标头,但在构建中却没有。如果您控制 API,则可以按照上述步骤解决问题。如果您不控制 API,您应该首先检查您的 HTTPS 配置是否有效,然后联系开发人员。

© www.soinside.com 2019 - 2024. All rights reserved.