什么是防盗链?如何实现防盗链?

一、什么是防盗链?

1、盗链

1) 盗链是指在自己的页面上展示一些并不在自己服务器上的内容。

假设建立了一个小的站点,是一个新站,里面没有内容,也没有什么相关的好看的图片,也没有视频,也没有mp3,也没有等等一些吸引人的静态资源文件。这时候看到别人的一些大站的一些资源相当的不错,此时就出现一个念头,把它直接链接过来,链接到网站中来,就可以了,这种行为就叫做盗链行为。当然有一部分人认为,盗链并不会对原服务器(即所盗链的那个服务器)产生影响,但是在这儿我们要说明一下,盗链本身不是一种很道德的行为,因为它会影响对方的服务器。

2) 整体来说,盗链是获得他人服务器上的资源地址,绕过别人的资源展示页面,直接在自己的页面上向最终用户提供此内容。

即不通过别人的页面来展示别人的资源,而是通过我们自己的页面来展示别人的资源,直接在自己的页面上向最终用户提供内容。这样对用户来说,他并不知道这个资源是谁的,他就认为理所当然就应该是你的,实际上,是从别人那 Copy 来的,这就叫做盗链。

3) 常见的是小站盗用大站的图片、音乐、视频、软件等资源。

如:我们建立一个图片的网站,我们看到百度里面有些图片是比较漂亮的,比较好的,我们可以把它拿过来,直接把那个链接复制过来即可;还有一种情况是,我们看到别人的站点里有一个mp3的音乐不错,我们可以把它放到我们的站点中来,当然也是通过链接的方式,包括视频,包括软件下载,都可以这样去做。

4) 通过盗链的方法可以减轻自己服务器的负担,因为真实的空间和流量均是来自别人的服务器。

如:我们在盗用别人的站点的时候,很多人去盗用它的站点,突然有一天他觉得我的流量用完了,而且我的PV也不差,这个时候他会认为我的整体站是不是比较好,大家是不是都比较喜欢,但其实一看自己的访问量还是很差,在这儿其实是被别人盗链了。其实对于我们来说也是,如果有一天我们发现我们的流量慢慢地在消失,但是我们PV统计,IP统计很少,这个时候我们就应该去考虑是不是被别人防盗链了。

注:虽然能减轻自己服务器的负担,但是增加了别人服务器的负担,因此这是一种不道德的行为。


2、防盗链行为

将别人网站的链接地址拿过来用。新建一个 demo.php,写入如下代码:

<img src="https://www.imooc.com/static/img/index/logo.png">

运行效果:

在这里插入图片描述

3、防盗链概念

  • 防止别人通过一些技术手段绕过本站的资源展示页面,盗用本站的资源,让绕开本站资源展示页面的资源链接失效;
  • 可以大大减轻服务器及带宽的压力。

二、防盗链的工作原理

1、通过 Referer 或者 签名,网站可以检测目标网页访问的来源网页,如果是资源文件,则可以跟踪到显示它的网页地址;

referer:判断 referer 是否与原网站的 referer 一致,不一致则禁止访问;

签名:通过签名的方式去防止,即在访问我们的资源的时候,在网址后面带一个参数,这个参数是我们彼此约定好的签名,这个签名的计算方式是我们彼此约定好的,我们把签名带上,服务器在显示该签名的时候,去判断该签名是否正确,相当于配了一把钥匙去开锁,如果没有问题,就显示图片。签名通常情况下设置要相当对复杂一点,不能让别人轻易猜到。如果我们设置了签名,当我们去访问该图片的时候,不知道签名的方式,此时就没有办法去请求该图片。

2、一旦检测到来源表示本站即进行阻止或者返回指定的页面;

3、通过计算签名的方式,判断请求是否合法,如果合法则显示,否则返回错误信息。


三、防盗链的实现方法

1、Referer

  • Nginx 模块 ngx_http_referer_module 用于阻挡来源非法的域名请求;
  • Nginx 指令 valid_referers,全局变量 $invalid_referer

valid_referes none | blocked | server_names | string … 的用法如下:

  • none :“Referer” 来源头部为空的情况;
  • blocked:“Referer” 来源头部不为空,但是里面的值被代理或者防火墙删除了,这些值都不以 http:// 或者 https:// 开头;
    server_names:“Referer” 来源头部包含当前的 server_names;
valid_referers none          // 代表 referer 为空时也合法【有 none】
valid_referers               // 代表 referer 为空不合法【没有 none】
valid_referers blocked 		// 通过代理或者防火墙对 referer 进行了删除
valid_referers server_names  // 信任地址(如:imooc.com; *.imooc.com等) 

打开配置 /usr/local/nginx/conf/nginx.conf

  • 对图片格式进行防盗链:
// 防盗链的实现方法
location ~.*\.(gif|jpg|png|flv|swf|rar|zip)$
{
    valid_referers none blocked imooc.com *.imooc.com; 
    if ($invalid_referer) {
        # return 403;
        rewrite ^/http://www.imooc.com/403.jpg;
    }
}
  • 对目录进行防盗链
// 防盗链的实现方法
location /images/
{
    valid_referers none blocked imooc.com *.imooc.com;
    if ($invalid_referer)
    {
    	# return 403;
        rewrite ^/http://www.imooc.com/403.jpg;
    }
}

传统防盗链遇到的问题:通过伪造Referer来实现盗链,可以使用加密签名解决该问题。


2、加密签名

  • 使用第三方模块 HttpAccessKeyModule 实现 Nginx防盗链;
  • accesskey on|off 模块开关;
  • accesskey_hashmethod md5 | sha-1 签名加密方式;
  • accesskey_arg GET参数名称;
  • accesskey_signature 加密规则(在PHP与Nginx中签名的加密规则要一致,这样才能通过,从而进行访问,否则无法进行访问);
// 防盗链的实现方法
location ~.*\.(gif|jpg|png|flv|swf|rar|zip)$
{
    accesskey on;
    accesskey_hashmethod md5;
    accesskey_arg "key";
    accesskey_signature "mypass$remote_addr"; // $remote_addr 客户端IP
}

对于整个签名来说,代表 我们去拿一个字符串去拼接客户端IP,通过 md5 加密得到签名,在PHP端也要这么做,去生成一个签名,去请求图片的时候,nginx 就会去判断签名,将签名进行 md5 加密,然后判断两个值是否一致,如果一致,显示图片;否则显示 403


例子:

① 配置 /usr/local/nginx/conf/nginx.conf

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
    accesskey on;
    accesskey_hashmethod md5;
    accesskey_arg sign;
    accesskey_signature "jason$remote_addr"; // 表示 "jason"字符串 + 客户端IP 通过md5加密得到签名
}

② 新建 demo2.php

// 客户端IP 进行md5 加密
$sign = mg5('jason', $_SERVER['REMOTE_ADDR']);
echo '<img src="./logo_new.png?sign='.$sign.'">'; // 该图片是本地存在的图片

注:该方法防盗链的效果是十分有效的,但是每次访问的时候,都要拼接一个 sign,比较繁琐。因此,以上两种方法,各有利弊。


猜你喜欢

转载自blog.csdn.net/studyphp123/article/details/84104352
今日推荐