一个内部使用对网盘系统,同事反馈登录进系统后页面一直在反复刷新,url上的登录token也在疯狂变化。很明显是因为后台没有成功判断到用户已经登录,导致页面一直跳转到登录授权服务器获取token。
这个问题在我到浏览器上也复现了,而我用safari,火狐则没有这个问题。只有Chrome会出现反复刷新。将问题反馈给负责系统后台到同事,神奇的是,他的Chrome并不会反复刷新。
登录同事说登录的token是从登录接口的referer请求头获取的,从日志上看发现我们的请求中referer并没有带上token,只有一个域名。有可能是链接上带的查询参数被Chrome处理掉了。由此,怀疑是Chrome最近有更新才出现了问题。
我查看了我和反馈的同事的Chrome版本是最新的Chrome85,而后台同事的Chrome是77。搜了一下Chrome85的更新内容,发现Chrome真的对请求的referer做了干预。提升了referer的安全性。
referer请求头
开讲referer之前先了解一下 referer 是干什么的:
Referer 请求头包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的。服务端一般使用 Referer 请求头识别访问来源,可能会以此进行统计分析、日志记录以及缓存优化等。
———— Referer - MDN - Mozilla
除了请求页面,页面里如果有图片等静态资源和接口请求,这些请求的referer就会是当前页面。比如www.a.com请求了api.a.com/login这个接口,api.a.com/login请求头中的referer就是www.a.com。如果www.a.com后面带了查询字符串,如www.a.com?test=1,则请求参数也会被referer带上,如
// request header
content-length: 4408
content-type: application/json; charset=UTF-8
referer: www.a.com?test=1
Chrome85 的 referer 策略修改
原本默认的 referer 策略(policy)是no-referrer-when-downgrade
,即允许referer带上来源页面地址上的请求参数,Chrome85将策略修改为strict-origin-when-cross-origin
,即如果请求地址与请求页面非同源,将只携带请求的域名,不会再带上来源页面地址的请求参数。
为什么使用strict-origin-when-cross-origin
增强隐私:使用strict-origin-when-cross-origin
将在请求非同源资源的时候,让referer只带上来源页面的源域名,不会暴露链接上的其他参数。
如何开启/关闭no-referrer-when-downgrade
目前只有Chrome85主动使用了no-referrer-when-downgrade
这个策略,如果要在其他浏览器开启这个策略,可以分别在前后端做配置:
前端在html页面配置:
<meta name="referrer" content="strict-origin-when-cross-origin" />
服务端可以在请求头上加上 Referer Policy
这个请求头:
Referer Policy: strict-origin-when-cross-origin
关闭strict-origin-when-cross-origin
前端在html设置:
<meta name="referrer" content="no-referrer-when-downgrade"" />
<!-- 对某个特定资源设置 referer 策略 -->
<img src="…" referrerpolicy="no-referrer-when-downgrade" />
服务端将Referer Policy
设置为no-referrer-when-downgrade
Referer Policy: no-referrer-when-downgrade
总结
本文介绍了一次referer策略修改引起对系统登录bug,介绍了referer头和如何从前后端调整referer策略以满足开发的需要。
参考文章
Referer - MDN - Mozilla
Referer and Referrer-Policy best practices
网友评论