前言
最近,当我将开发完的新项目接口丢给前端仔去调用,正准备去摸鱼时,我的前端同事突然告诉我,我跨域配置没打开。我说这怎么可能,我这可是祖传代码,该配置的响应头都配置了,例如下面的代码demo
1 | resp.setHeader("Access-Control-Allow-Methods","*"); |
我说你不要诈我,但很快我就看到了一张图,啥时候cookie多了个SameSite
字段?我说别慌!待我研究一下这是啥
SameSite
在chrome51
版本开始之后,就为Cookie引入了一个SameSite
字段,说是用于防止CSRF
攻击,CSRF攻击我们就很熟悉了,那么它是怎么防止的呢?
Strict
这是最为严格的状态,完全禁止非本站点的Cookie
,当跨站点发送请求时,任何情况下都不会发送该Cookie
,只有请求与本站点一致的URL才会携带Cookie。不过这种限制太过严格,所以他不是SameSite
属性的默认值
1 | Set-Cookie: CookieName=CookieValue; SameSite=Strict; |
Lax
Lax规则类似于Strict,不过它相对于Strict会放宽一点,但是导航到其他网站的Get请求还是会携带Cookie的。因此SameSite默认值就为是Law
1 | Set-Cookie: CookieName=CookieValue; SameSite=Lax; |
None
None则将会在所有跨站点请求中都会携带Cookie,不过这可不意味着没有SameSite
属性一样,当为None
时,需要有Secure
属性,这就意味着只能通过HTTPS
协议进行通信,HTTP
请求是无法使用Secure
属性的。
1 | Set-Cookie: CookieName=CookieValue; SameSite=None; Secure |
解决方法
在了解SameSite属性的作用后,我终于知道为啥祖传代码没有作用了,因此我们只能想想其他办法来解决跨域验证的问题。
不用高版本浏览器
由于SameSite
属性只在高版本浏览器才支持,具体可以看这个地方SameSite cookies - HTTP | MDN (mozilla.org),或者可以在浏览器设置中关闭这个SameSite
配置。不过当我讲给产品经理听时,他说你明天可以不用来了
配置代理服务器
在开发时让前端在本地配置一个代理服务器,将端口号设置与项目设置为一致,根据同源策略,浏览器就不会进行限制了。具体操作就让前端仔进行操作啦。
后端解决
换个赛道
Cookie这么麻烦,那么我们就不用Cookie,直接换成基于Oauth2规范的Token来进行用户权限校验等功能。这个需要开发团队进行友好沟通,技术评估!
搞上HTTPS
如果沟通不过那就为测试服务器添加上SSL证书,并将添加上SameSite的None值,以满足浏览器的跨域限制。