记一次浏览器SameSite策略更新,导致接口 Failed to load response data 的解决过程

问题

vue项目,本地开发本来好好的,浏览器升级后,突然就不行了。连页面都没渲染到app上,白屏了,如下:

Snip20220120_2.png

虽然本地开发无法加载页面了,但是npm run build后打包发布的代码,浏览器可以正常访问,完全没问题。

项目登录认证页面,是公司另外部门封装的一个统一认证页面,短期是无法通过代码层面解决问题的,所以看看浏览器更新后,发生了什么,看看能不能解决了。

寻因

在开发者工具的Network里,找到登录认证的几个请求接口,发现有2个关键的接口,都返回了如下信息:

1
Failed to load response data: No resource with given identifier found

接口无返回认证信息,导致渲染页面的流程也走不下去了,造成了页面渲染失败,白屏。

再看看控制台打印,发现Console里面有了新的告警,如下:

1
由于 Cookie “JSESSIONID”缺少“SameSite”属性,且该属性的默认值为“SameSite=Lax”,已将“SameSite”的策略设为“Lax”。
1
由于 Cookie “”缺少“SameSite”属性,且该属性的默认值为“SameSite=Lax”,已将“SameSite”的策略设为“Lax”。

SameSite是 Chrome 51 版本后添加的一个属性,用来防止 CSRF 攻击和用户追踪(相关资料)。

SameSite有3个属性:

  • Strict 最为严格,完全禁止第三方Cookie,跨站点时,任何情况下都不会发送Cookie。只有当前网页URL与请求目标URL完全一致才会带上Cookie。

  • Lax 规则稍稍放宽,大多数情况也是不发送第三方Cookie,但是导航到目标网址的 Get 请求除外。

  • None 网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。

通过以上信息,知道,更新后的浏览器,安全要求,接口报文里面的set-cookie要设置SameSite 属性,默认将没有设置SameSite的请求设置为SameSite=Lax

项目认证接口,在本地开发的情况下,是跨站点&跨域 Get 请求,接口没有设置SameSite属性,在浏览器默认设置SameSite=Lax的情况下,导致请求没带上Cookie,认证失败,接口不会返回数据,导致了接口Failed to load response data的问题。

发布生产时,认证接口是同源&同站点 Get 请求,就没问题了。

解决方案

1、Chrome 51版本后91版本前

运行本地项目调试时,某些接口需要使用cookie来校验,会涉及到cookie跨域丢失问题。对于前端来说,调试项目时想要实现浏览器跨域共享cookie,可以设置浏览器的实验属性,关闭浏览器的安全设置,操作如下:

  • 在Chrome地址栏输入chrome://flags
  • SameSite by default cookiesCookies without SameSite must be secure 设置成Disabled

Snip20220120_3.png

  • 重启浏览器生效

2、Chrome 91版本后

Chrome 91 版本后,Chrome实验属性 SameSite by default cookiesCookies without SameSite must be secure 的设置消失了。临时解决办法就是安装旧版本的Chrome,因为本人是Mac下开发,只分享下Mac下安装旧版本浏览器的办法。

Mac下谷歌浏览器稳定版、dev版的旧版不能和新版共存,如果更新了最新浏览器,又不想降版本的,可以下载谷歌浏览器canary版(可以和稳定版、dev版共存),各版本下载地址,选择91前的版本,然后照着 1 的操作设置下就ok了。

3、接口设置SameSite=none

服务端将 response 的 header 设置Set-Cookie:SameSite=None,允许跨站请求发送 Cookie。

1
Set-cookie: key=value; SameSite=None; Secure
  • 注意1:接口必须是https
  • 注意2:需要 UA 检测,部分浏览器不能加 SameSite=none

IOS 12的 Safari 以及老版本的一些 Chrome 会把 SameSite=none 识别成 SameSite=Strict,所以服务端必须在下发 Set-Cookie 响应头时进行 User-Agent 检测,对这些浏览器不下发SameSite=none属性

4、用火狐

不知道Windows下什么情况,反正Mac很幸运的,在升级 96 版本后也不行了。

总结

当接口依赖Cookie时,前端不发送Cookie,会造成接口不返回数据的问题。也就是文章开头的
Failed to load response data: No resource with given identifier found问题。

浏览器对前端安全和用户隐私越来越重视了,现在是浏览器默认策略倒逼接口安全升级了。

一些通用服务接口,最好是服务端设置解决了。不然第三方开发过程中,遇到本文所述问题,真的很无语的,说是前端的问题也行,说不是前端的问题,貌似也没错。随着浏览器安全策略的不断更新,服务端接口的安全策略也要随着更新了,特别是一些不需要收集用户信息、不搞广告的项目,生产环境严格执行SameSite的安全策略其实也没啥问题的,反而更好。供第三方开发时,说明下注意的设置就好了。

参考资料