如何解决防盗链的 Referrer 问题

in 寻寻觅觅 with 4 comments

最近在为 onepoint 项目添加阿里云盘子模块,发现上手有点晚了。最初有朋友在 github 上发过相关的 issue,因为一些原因一直没做。开始做的时候才发现,阿里云盘已经变”狡猾“了,设置了referrer 验证。

要想解决这个问题,要先弄清楚 referrer 是什么

referrer 是什么

Referrer 是 HTTP 请求头里面包含的一个字段,内容是一个 URL,表示当前页面是通过这个 URL 里的链接进入的、或者当前资源是被这个 URL 引用的。因此服务器可以利用 referer(历史原因,拼写错误,后来就一直这样沿用了,下文统称为 referrer) 请求头字段来判断访问来源,获取用户浏览的历史记录。

referrer 验证

因为 referrer 的特点,有一些服务器会根据 referrer 的内容判断请求源是否源于自己的服务器,然后或接受或拒绝该请求。

以阿里云的下载链接为例,通常情况下,如果是在阿里云盘的网站点击的这个链接,referrer 就是阿里云盘,如果是在本站打开的,那么referer 就是 https://www.onesrc.cn。阿里云也就可以根据这一点判断是否允许让用户下载文件,如下图所示。

image-20210426120650830.png

referrer 策略

现在的浏览器已经可以支持对 referrer 发送情况进行控制,referrer 的默认策略如下:

当访问一个网页里面包含的链接时,浏览器会自动加上 referrer 请求字段。

但在以下两种情况下,referrer 不会被发送:

除了默认策略,还可以通过 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

如何去除

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://stackoverflow.com/questions/55882899/how-not-to-loose-referer-value-on-301-https-redirects-in-Cloudflare-workers

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referer

https://www.zhihu.com/question/37101927

附录

附上一个可以查看 http 请求头的工具

https://point.onesrc.cn/ip/

上一篇: 2021 如何优雅地使用 flash
下一篇: 2022春晚节目单
Responses
  1. LZ

    你好,电脑端解决了,但是移动端还是有问题 求教!

    Reply
    1. _ukuq
      @LZ

      有链接参考吗?可以先用chrome移动端试试看,可能是浏览器不支持

      Reply
      1. lz
        @_ukuq

        确实是浏览器不支持,还包括微信内置浏览器。正在研究怎么。跳出内置浏览器……

        Reply
  2. 111

    1111中

    Reply