运行机制:
我们项目中的一个页面B。被第三方用户A页面通过iframe方式嵌入到其中的。运行的机制是:A页面中iframe src指向我们项目中的一个接口,然后将要调用的页面通过参数传递过去。例如:http://www.aa.com/authtype?redirect=http://www.aa.com/b.html&sign=签名。在authtype接口中通过sign签名得出我们页面B中用的token,写入cookie,然后重定向到B页面。这样B页面发送请求会自动代入cookie,其中带有token,实现验证。
问题分析:
然而在Chrome 80版本中,Chrome会将没有声明SameSite值的cookie默认设置为SameSite=Lax。只有采用SameSite=None; Secure。设置的cookie可以从外部访问,前提是通过安全连接(即HTTPS)访问。
意思是在Chrome 80版本中,这种通过iframe导致两个站名不同,然后导致写不进去cookie。
什么是SameSite
SameSite是Cookie中的一个属性,它用来标明这个 cookie 是个“同站 cookie”,“同站 cookie” 只能作为第一方cookie,不能作为第三方cookie,因此可以限制第三方Cookie,解决CSRF的问题。早在Chrome 51中就引入了这一属性,但是不会默认设置,所以相安无事。
第三方Cookie:由当前a.com页面发起的请求的 URL 不一定也是 a.com 上的,可能有 b.com 的,也可能有 c.com 的。我们把发送给 a.com 上的请求叫做第一方请求(first-party request),发送给 b.com 和 c.com 等的请求叫做第三方请求(third-party request),第三方请求和第一方请求一样,都会带上各自域名下的 cookie,所以就有了第一方cookie(first-party cookie)和第三方cookie(third-party cookie)的区别。上面提到的 CSRF 攻击,就是利用了第三方 cookie可以携带发送的特点 。
“同站cookie”不是根据同源策略判断,而是PSL(公共后缀列表),子域名可以访问父域名cookie,但父域名无法访问子域名cookie。
此部分参考:谷歌浏览器新版本Chrome 80默认SameSite导致跨域登录状态失效的问题
解决方法:
- 浏览器显式关闭该功能。(不推荐,不能要求用户这样做,但是这个功能还是蛮有用的)
地址栏输入:chrome://flags/
搜索SameSite。将SameSite by default cookies和Cookies without SameSite must be secure两项设置为 Disable - 通过服务端关闭SameSite属性。(此种方法没有验证成功,如果大家有知道具体细节的欢迎告诉我。)
response.setHeader( "Set-Cookie", "token=xxxx; SameSite=None; Secure=true")
设置后响应头有修改,但是仍写不进去cookie。图片是没有加token的,加了也不行。在控制台的Application里面看不到。
-
后端将token通过重定向的URL传递到前端。(这种情况下,前端也存不进去cookie)采用将token存入到localStorage中。然后取都用localStorage。流程图如下。
image.png
补充说明一下:网上有说不要用cookie验证,改成用token验证。不同于我的问题。我们的项目就是用的token验证,只不过是后台通过存入cookie把token给前端用于其他的请求。可以查看登录的两种方式
网友评论