最近在为 onepoint 项目添加阿里云盘子模块,发现上手有点晚了。最初有朋友在 github 上发过相关的 issue,因为一些原因一直没做。开始做的时候才发现,阿里云盘已经变”狡猾“了,设置了referrer 验证。
要想解决这个问题,要先弄清楚 referrer 是什么
referrer 是什么
Referrer 是 HTTP 请求头里面包含的一个字段,内容是一个 URL,表示当前页面是通过这个 URL 里的链接进入的、或者当前资源是被这个 URL 引用的。因此服务器可以利用 referer(历史原因,拼写错误,后来就一直这样沿用了,下文统称为 referrer) 请求头字段来判断访问来源,获取用户浏览的历史记录。
referrer 验证
因为 referrer 的特点,有一些服务器会根据 referrer 的内容判断请求源是否源于自己的服务器,然后或接受或拒绝该请求。
以阿里云的下载链接为例,通常情况下,如果是在阿里云盘的网站点击的这个链接,referrer 就是阿里云盘,如果是在本站打开的,那么referer 就是 https://www.onesrc.cn
。阿里云也就可以根据这一点判断是否允许让用户下载文件,如下图所示。
referrer 策略
现在的浏览器已经可以支持对 referrer 发送情况进行控制,referrer 的默认策略如下:
当访问一个网页里面包含的链接时,浏览器会自动加上 referrer 请求字段。
但在以下两种情况下,referrer 不会被发送:
- 来源页面采用的协议为表示本地文件的 "file" 或者 "data" URI;
- 当前请求页面采用的是非安全协议,而来源页面采用的是安全协议(HTTPS)。
除了默认策略,还可以通过 Referrer-Policy,对 referrer 的发送情况进行更精准的控制。
Referrer-Policy
Referrer-Policy 有多种策略,其名称如下:
Referrer-Policy: no-referrer
Referrer-Policy: no-referrer-when-downgrade
Referrer-Policy: origin
Referrer-Policy: origin-when-cross-origin
Referrer-Policy: same-origin
Referrer-Policy: strict-origin
Referrer-Policy: strict-origin-when-cross-origin
Referrer-Policy: unsafe-url
- no-referrer,无referrer
- no-referrer-when-downgrade,默认策略
- origin,仅发送文件的源作为引用地址。例如
https://example.com/page.html
会将https://example.com/ 作为引用地址。
- origin-when-cross-origin,对于同源的请求,会发送完整的URL作为引用地址,但是对于非同源请求仅发送文件的源。
- same-origin,对于同源请求会发送引用地址,但是对于非同源请求则不发送引用地址信息。
- strict-origin,在同等安全级别的情况下,发送文件的源作为引用地址(HTTPS->HTTPS),但是在降级的情况下不会发送 (HTTPS->HTTP)。
- strict-origin-when-cross-origin,对于同源的请求,会发送完整的URL作为引用地址;在同等安全级别的情况下,发送文件的源作为引用地址(HTTPS->HTTPS);在降级的情况下不发送此首部 (HTTPS->HTTP)。
- unsafe-url,无论是同源请求还是非同源请求,都发送完整的 URL(移除参数信息之后)作为引用地址。
如何去除
- referrer 是因网页链接而产生的,换句话说,如果直接在浏览器中输入网址,就不会有 referrer 了,这是最简单的方式。
- 另一种就是通过Referrer-Policy了
HTML网页集成
像 <a>、<area>、<img>、<iframe>、<script> 或者 <link>
这些都是可以包含一个链接的,如果需要对这里的 referrer 进行控制,可以通过 referrerpolicy
属性。
例如:
<a href="http://example.com" referrerpolicy="origin">
<a href="http://example.com" rel="noreferrer">
还可以通过 meta 修改网页的默认策略:
在 head 里面添加一个 referrer 策略
<meta name="referrer" content="origin">
通过301、302
除了网页集成,像 301、302 这样的跳转状态码,通常来说浏览器是不会再去获取响应体,因而响应头里面包含了这样一个字段Referrer-Policy
,浏览器可以根据这个字段决定 referrer 的发送情况。
例如 Referrer-Policy: same-origin
。
解决阿里防盗链
防盗链一般都会允许空 referrer,否则在浏览器中单独输入这个链接就访问不了里面的内容了。
阿里云盘也是如此,其策略是,referrer 可以没有,如果有,必须是俺们阿里家的。
onepoint 的解决思路也很简单:
对于网页预览时产生的 referrer,在 head 里面添加一个默认的同源策略。
<head>
<meta charset="utf-8">
<meta name="github" content="https://github.com/ukuq/onepoint">
<meta name="referrer" content="same-origin">
</head>
对于下载时,302 跳转带的 referrer,通过在响应头里面添加一个 Referrer-Policy: same-origin
即可解决。
例如:
HTTP/1.1 302 Moved Temporarily
Content-Type: text/html; charset=utf-8
Location: https://xxxxxx
referrer-policy: same-origin
参考链接
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referer
https://www.zhihu.com/question/37101927
附录
附上一个可以查看 http 请求头的工具
本文由 ukuq 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Apr 26, 2021 at 12:11 pm
你好,电脑端解决了,但是移动端还是有问题 求教!
有链接参考吗?可以先用chrome移动端试试看,可能是浏览器不支持
确实是浏览器不支持,还包括微信内置浏览器。正在研究怎么。跳出内置浏览器……
1111中