对象存储BOS

    防盗链

    简介

    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白名单,能实现防盗链功能。

      image.png

      测试结果如下:

      浏览器输入 说明 结果
      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白名单,能实现防盗链功能。

      image.png

      测试结果如下:

      浏览器输入 说明 结果
      http://bos-test-f.bj.bcebos.com/bos.jpg 直接访问,Referer为空 访问成功
      http://test.com/index 请求来自于源站,Referer不为空 访问成功
      http://test-steal.com/index 请求来自于盗链网站 BOS返回403,防盗链成功。
    • 只设置Bucket的的访问控制为“不允许referer为空”,不能实现防盗链功能,所以不推荐该配置。

      image.png

      测试结果如下:

      浏览器输入 说明 结果
      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结果

    • 过期拒绝访问结果

    上一篇
    使用CDN加速BOS
    下一篇
    如何解决浏览器跨域CORS问题