防盗链
简介
A网站将自己的静态资源如图片或视频等存放在百度智能云存储的BOS上。B网站在未经A允许的情况下,使用A网站的图片或视频资源,放置到自己的网站中。由于BOS是按照使用量收费,这样网站B盗取了网站A的空间和流量,而A没有获取任何利益却承担了资源使用费。B盗用A资源放到自己网站的行为即为盗链。
原理
防盗链的主要方法是通过限制引用页来实现的,有设置Referer防盗链和设置签名URL防盗链两种方式。
- 设置Referer防盗链的原理将HTTP请求表头的Referer属性(保存了该请求是从哪个URL发送到服务器的)和服务端许可的白名单进行比对,如果一致则表明是站内请求,或者为自己信任的站点请求,否则视为盗链。
- 但是Referer属性可以被恶意的篡改,针对这种情况,可以通过签名URL来实现防盗链。
配置BOS防盗链功能
设置Referer防盗链
什么是Referer
Referer是HTTP请求表头的一个参数,不同场景下HTTP请求表头的Referer属性会有差异:
- 直接访问服务器端资源:即浏览器直接请求BOS的资源,则HTTP请求中不包含Referer属性
- 在网站A中引用BOS的资源:浏览器访问的是网站test.com的index页面,该页面上引用了BOS的资源。浏览器向BOS请求资源时,HTTP的请求头中包含了Referer属性,该属性指明是
http://test.com/index
页面引用了该资源。
不同Referer设置的测试结果
为了测试防盗链的功能需要搭建两个网站,域名分别为源网站test.com和盗链网站test-steal.com。在这两个网站下分别部署一个index页面,该页面引用了BOS的图片资源。code如下:
配置Bucket的Referer操作及原理请参考设置Referer白名单。下面详细介绍不同设置对应的不同测试结果:
-
设置Bucket的访问控制为“不允许refer为空”的同时也设置Referer白名单,能实现防盗链功能。
测试结果如下:
浏览器输入 说明 结果 http://bos-test-f.bj.bcebos.com/bos.jpg
直接访问,Referer为空 不允许空Referer的请求,返回403 http://test.com/index
请求来自于源站,Referer不为空 访问成功 http://test-steal.com/index
请求来自于盗链网站 BOS返回403,防盗链成功。 -
设置"允许refer为空”的同时也设置Referer白名单,能实现防盗链功能。
测试结果如下:
浏览器输入 说明 结果 http://bos-test-f.bj.bcebos.com/bos.jpg
直接访问,Referer为空 访问成功 http://test.com/index
请求来自于源站,Referer不为空 访问成功 http://test-steal.com/index
请求来自于盗链网站 BOS返回403,防盗链成功。 -
只设置Bucket的的访问控制为“不允许referer为空”,不能实现防盗链功能,所以不推荐该配置。
测试结果如下:
浏览器输入 说明 结果 http://bos-test-f.bj.bcebos.com/bos.jpg
直接访问,Referer为空。 不允许空Referer的请求,返回403 http://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框架来调用BOS的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 Test
img(src="#{signedUrl}")
测试结果
如图所示,每次访问该页面时都会重新生成一个签名的URL来访问BOS的资源,该签名的URL是有过期时间的。如果过期则返回403错误拒绝访问,从而实现防盗链功能。
-
未过期签名URL结果
-
过期拒绝访问结果