背景:
最近遇到了一个跨域无法携带 cookie 的问题。即我在前后端设置无误的情况下跨域,可以正常发送请求但是无法携带 cookie。
最后经过一番搜索找到了问题的原因,并在此进行记录一下。
什么是跨域?
跨域是浏览器的一种保护措施。防止一些恶意网站将一些链接以某种形式嵌入在网站中,用户不经意间点击链接,其实就会向链接发送了一个请求。如果请求可以随意携带上 cookie ,那就存在了安全问题,比如使用用户的 cookie 进行一些购物操作等,在用户不知情的情况下进行恶意操作。
因此浏览器限制了不同域名的请求如果没有设置 CORS 是不接受返回的。而且如果没有在前端设置 credential 且在后端返回头设置 access-allow-credential 和 access-control-allow-origin 写明请求 url, 就不会携带 cookie 的。
跨域的常用解决方式
解决跨域最常用的方式是使用 CORS(跨域资源共享)。
后端设置返回头:
//前端请求不携带 cookie:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Content-Type
//前端请求携带 cookie
Access-Control-Allow-Origin: 这里填写前端请求具体的url
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-control-allow-credentials:true
若要携带 cookie,同时需要在前端设置 withCredentials : true
一般这样设置就可以在不同域名的情况下发送请求并且接收到返回消息,并且可以携带 cookie
无法携带 cookie 原因
我虽然前后端都按照上面的配置了,按理说应该会携带 cookie。但是没有携带。原因是 chrome 2020年新版本的浏览器更改了 cookie 的一个属性:samesite
以前版本的 samesite 默认值是 none ,即只要配置了上述的 cors 跨域就可以带上 cookie。但是现在的默认值改成了 lax ,即只能在主域名相同情况下携带 cookie
举个例子,在配置了 cors 情况下:
test.edu.com
可以向 aaa.edu.com
发送跨域请求并携带 cookie
test.edu.com
向 bbb.net.com
发送请求,但不能携带 cookie
原因是 test.edu.com
的主域名是 edu.com
,bbb.new.com
的主域名是 .new.com
这两个域名的主域名不同就不能发送 cookie
samesite 介绍:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie/SameSite
解决方法
-
在 chrome 中输入 chrome://flags/ 把 samesite 关闭就好了
-
将请求换成 https,然后设置 samesite 为none 且同时 secure 为 true
为什么需要 https ,因为设置 secure 只能 https -
跨域请求在一个主域名下面