阿里云对象存储防盗链的配置方法

A网站将自己的静态资源如图片或视频等存放在阿里云存储的阿里云对象存储上。B网站在未经A允许的情况下,使用A网站的图片或视频资源,放置到自己的网站中。由于阿里云对象存储是按照使用量收费,这样网站B盗取了网站A的空间和流量,而A没有获取任何利益却承担了资源使用费。B盗用A资源放到自己网站的行为即为盗链。

阿里云对象存储防盗链

防盗链的主要方法是通过限制引用页来实现的,有设置Referer防盗链和设置签名URL防盗链两种方式。

  • 设置Referer防盗链的原理将HTTP请求表头的Referer属性(保存了该请求是从哪个URL发送到服务器的)和服务端许可的白名单进行比对,如果一致则表明是站内请求,或者为自己信任的站点请求,否则视为盗链。
  • 但是Referer属性可以被恶意的篡改,针对这种情况,可以通过签名URL来实现防盗链。

配置阿里云对象存储防盗链功能

设置Referer防盗链

什么是Referer

Referer是HTTP请求表头的一个参数,不同场景下HTTP请求表头的Referer属性会有差异:

  • 直接访问服务器端资源:即浏览器直接请求阿里云对象存储的资源,则HTTP请求中不包含Referer属性
  • 在网站A中引用阿里云对象存储的资源:浏览器访问的是网站test.com的index页面,该页面上引用了阿里云对象存储的资源。浏览器向阿里云对象存储请求资源时,HTTP的请求头中包含了Referer属性,该属性指明是http://test.com/index页面引用了该资源。

不同Referer设置的测试结果

为了测试防盗链的功能需要搭建两个网站,域名分别为源网站test.com和盗链网站test-steal.com。在这两个网站下分别部署一个index页面,该页面引用了阿里云对象存储的图片资源。code如下:

配置Bucket的Referer操作及原理请参考设置Referer白名单。下面详细介绍不同设置对应的不同测试结果:

  • 设置Bucket的访问控制为“不允许refer为空”的同时也设置Referer白名单,能实现防盗链功能。

    测试结果如下:

    浏览器输入说明结果http://bos-test-f.bj.bcebos.com/bos.jpg直接访问,Referer为空不允许空Referer的请求,返回403http://test.com/index请求来自于源站,Referer不为空访问成功http://test-steal.com/index请求来自于盗链网站阿里云对象存储返回403,防盗链成功。

  • 设置"允许refer为空”的同时也设置Referer白名单,能实现防盗链功能。

    测试结果如下:

    浏览器输入说明结果http://bos-test-f.bj.bcebos.com/bos.jpg直接访问,Referer为空访问成功http://test.com/index请求来自于源站,Referer不为空访问成功http://test-steal.com/index请求来自于盗链网站阿里云对象存储返回403,防盗链成功。

  • 只设置Bucket的的访问控制为“不允许referer为空”,不能实现防盗链功能,所以不推荐该配置。

    测试结果如下:

    浏览器输入说明结果http://bos-test-f.bj.bcebos.com/bos.jpg直接访问,Referer为空。不允许空Referer的请求,返回403http://test.com/index请求来自于源站,Referer不为空访问成功http://test-steal.com/index请求来自于盗链网站,但是Referer不为空访问成功。

Referer防盗链的优缺点

Referer防盗链的优点是设置简单,控制台即可操作。缺点是无法防止恶意伪造Referer,如果盗链是通过应用程序模拟HTTP请求伪造Referer,则会绕过用户防盗链设置。如果对防盗链有更高要求的则需要通过签名URL实现防盗链。

配置签名URL防盗链

签名URL防盗链的原理即将文件设为私有访问,然后生成一个预签名的URL,提供给用户一个临时的访问UEL。生成预签名URL时可以通过指定URL的有效时长限制用户长时间访问。如调用Java SDK实现预签名的URL请参考获取Object的URL。

签名URL防盗链使用nodejs的sails框架来调用阿里云对象存储的javascript SDK来实现该功能,可以在code中指定URL的过期时间expirationInSeconds,具体实现code如下:

var BosClient = require("@baiducloud/sdk").BosClient;module.exports = { showImage:function(req,res){ var config = { endpoint: "http://bj.bcebos.com", credentials: { ak: "AK", //您的AK sk: "SK" //您的SK } }; var client = new BosClient(config); var bucketName = "bos-test-f"; var key = "bos.jpg"; var timestamp = Date.now() / 1000; var expirationInSeconds = 1800; var headers = {}; var params = {}; var headersToSign = {}; var signedUrl = client.generatePresignedUrl(bucketName, key, timestamp, expirationInSeconds, headers, params, headersToSign, config); return res.view("image", {signedUrl : signedUrl}); }};

指定image资源的地址为签名URL:

Hi Testimg(src="#{signedUrl}")

测试结果

,每次访问该页面时都会重新生成一个签名的URL来访问阿里云对象存储的资源,该签名的URL是有过期时间的。如果过期则返回403错误拒绝访问,从而实现防盗链功能。

  • 未过期签名URL结果

  • 过期拒绝访问结果