CORS Cookie 未在跨域上设置,使用提取,设置凭据:'include' 并且已设置来源
CORS Cookie not set on cross domains, using fetch, set credentials: 'include' and origins have been set
我正在使用 fetch 向后端发出请求。
当我使用不同的域时,cookie 未设置。
当我使用同一个域时设置了 cookie。
为什么没有设置?
我修改了我的 /etc/hosts 文件以使用假名来测试使用相同和不同的域,并确保它们都是 not blacklisted by the browser。
如果我对浏览器域和服务器域都使用 local-test-frontend.com
它可以工作,但是如果我将后端 url 更改为 local-test-backend.com
它会失败。
*请注意,我测试的前端 url 是 * http://local-test-frontend.com:3000/login
Javascript
fetch('http://local-test-backend.com/login', {
mode: 'cors',
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(loginRequest),
credentials: 'include'
}).then(// Other code here.....
服务器响应Headers
Access-Control-Allow-Credentials
true
Access-Control-Allow-Origin
http://local-test-frontend.com:3000
Content-Length
103
Content-Type
application/json
Date
Wed, 10 Jul 2019 07:23:49 GMT
Server
Werkzeug/0.15.1 Python/3.7.3
Set-Cookie
MY_TOKEN=a7b8ad50f19…end.com; Path=/; SameSite=Lax
I'm just trying to get a cookie set for my current domain by calling a server on a different domain.
你不能,至少不能直接。 Cookie 属于设置它们的来源。
最接近的是将不同域 return 格式为 non-Cookie 的数据(例如响应的正文),然后使用 client-side JS 来存储它使用 document.cookie
.
截至 2021 年 Linux 上的 Edge 90.0.796.0,我设法使用以下方法设置 CORS cookie:
- 客户端使用
credentials: 'include'
异步初始化获取请求。有关详细信息,请参阅 here。
- 要执行 CORS,服务器响应 header 必须包含
Access-Control-Allow-Origin
明确设置为域,可以不同于服务器域。例如,在 Single-Page-App 架构中,您的前端站点临时托管在 localhost:3000,您的后端服务器托管在 localhost:8000,那么 header 应该是 Access-Control-Allow-Origin: http://localhost:3000
.参见 here and here。
- 为了允许客户端处理 cookie,这显然是一种敏感资源,服务器响应 header 必须进一步包含
Access-Control-Allow-Credentials: true
。请参阅 here. Note that this enforces a non-wildcard setting for Access-Control-Allow-Origin
. See here - 这就是为什么在上面的第 2 点中,它必须明确设置为 http://localhost:3000
而不是 *
- 当服务器设置cookie时,它必须包含
SameSite=None; Secure; HttpOnly
。所以总体上类似于 Set-Cookie: session_id=12345; SameSite=None; Secure; HttpOnly
。 SameSite
在最新的浏览器中似乎是一个相对的 new requirement,当 SameSite
设置为 None
. 时必须与 Secure
一起使用
- 关于
HttpOnly
,我没有找到相关资料,但在我的实验中,省略它导致浏览器忽略Set-Cookie
header。
- 对后端服务器的进一步请求也必须设置
credentials: 'include'
。
我正在使用 fetch 向后端发出请求。 当我使用不同的域时,cookie 未设置。 当我使用同一个域时设置了 cookie。
为什么没有设置?
我修改了我的 /etc/hosts 文件以使用假名来测试使用相同和不同的域,并确保它们都是 not blacklisted by the browser。
如果我对浏览器域和服务器域都使用 local-test-frontend.com
它可以工作,但是如果我将后端 url 更改为 local-test-backend.com
它会失败。
*请注意,我测试的前端 url 是 * http://local-test-frontend.com:3000/login
Javascript
fetch('http://local-test-backend.com/login', {
mode: 'cors',
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(loginRequest),
credentials: 'include'
}).then(// Other code here.....
服务器响应Headers
Access-Control-Allow-Credentials
true
Access-Control-Allow-Origin
http://local-test-frontend.com:3000
Content-Length
103
Content-Type
application/json
Date
Wed, 10 Jul 2019 07:23:49 GMT
Server
Werkzeug/0.15.1 Python/3.7.3
Set-Cookie
MY_TOKEN=a7b8ad50f19…end.com; Path=/; SameSite=Lax
I'm just trying to get a cookie set for my current domain by calling a server on a different domain.
你不能,至少不能直接。 Cookie 属于设置它们的来源。
最接近的是将不同域 return 格式为 non-Cookie 的数据(例如响应的正文),然后使用 client-side JS 来存储它使用 document.cookie
.
截至 2021 年 Linux 上的 Edge 90.0.796.0,我设法使用以下方法设置 CORS cookie:
- 客户端使用
credentials: 'include'
异步初始化获取请求。有关详细信息,请参阅 here。 - 要执行 CORS,服务器响应 header 必须包含
Access-Control-Allow-Origin
明确设置为域,可以不同于服务器域。例如,在 Single-Page-App 架构中,您的前端站点临时托管在 localhost:3000,您的后端服务器托管在 localhost:8000,那么 header 应该是Access-Control-Allow-Origin: http://localhost:3000
.参见 here and here。 - 为了允许客户端处理 cookie,这显然是一种敏感资源,服务器响应 header 必须进一步包含
Access-Control-Allow-Credentials: true
。请参阅 here. Note that this enforces a non-wildcard setting forAccess-Control-Allow-Origin
. See here - 这就是为什么在上面的第 2 点中,它必须明确设置为http://localhost:3000
而不是*
- 当服务器设置cookie时,它必须包含
SameSite=None; Secure; HttpOnly
。所以总体上类似于Set-Cookie: session_id=12345; SameSite=None; Secure; HttpOnly
。SameSite
在最新的浏览器中似乎是一个相对的 new requirement,当SameSite
设置为None
. 时必须与 - 关于
HttpOnly
,我没有找到相关资料,但在我的实验中,省略它导致浏览器忽略Set-Cookie
header。 - 对后端服务器的进一步请求也必须设置
credentials: 'include'
。
Secure
一起使用