先说一下含义,就是想让nginx里的静态资源只供它反向代理连接的内部服务器去访问,其他人想访问,就不给。比如01虚拟机充当nginx服务器,它里面存了很多静态资源,04虚拟机proxy_pass到01虚拟机,想访问它的页面,01虚拟机不想让你通过这种方式拿到我的静态资源,于是可以设置防盗链。举个例子,我proxy_pass到尚硅谷的主页,肯定要访问它的域名背后的nginx服务器,正常来说该服务器保存了很多静态资源,然后该nginx去将本次访问的任务分配给某个内部服务器。如果nginx服务器设置了防盗链,那么我proxy_pass拿到的尚硅谷的主页将无法获取静态资源,看不到图片,css失效,js失效等等。
演示
- 思路:01虚拟机作为nginx服务器,保存静态资源,02虚拟机作为内部服务器,提供tomcat服务,03虚拟机作为外部用户,在03里配置proxy_pass访问01。01设置防盗链,不让03获取静态资源。
- 01配置文件:03虚拟机配置一个反向代理到01的对应端口下即可,不赘述。02虚拟机沿用动静分离之后的配置即可,主要是要修改01虚拟机的配置文件,如下:
server {
listen 82;
listen [::]:82;
#root /var/www/web/index;
#index index.html;
server_name localhost;
location / {
proxy_pass http://192.168.125.129:8080/demo/views/login.html;
#try_files $uri $uri/ =404;
}
location ~*/(js|img|css|layui|assembly) {
valid_referers 192.168.xxx.xxx;
if ($invalid_referer) {
return 403;
}
root /var/www/web ;
index index.html index.htm;
}
}
valid_referers 192.168.xxx.xxx;此处是01虚拟机的ip,这里valid_referers匹配的是网址,带有这个ip的网址,都会触发valid_referers。防盗链的实现是通过referer检测的,大致的原理是正常的浏览器会在资源第二次访问时提供referer地址,也就是访问者的来源。
所谓第二次访问,其实当你访问某个网址的时候,先加载这个,
可以看到是没有referer的,因为算作第一次访问,但是后面紧跟的静态资源的请求就不是第一次了,而是多次了,此时就带有referer了:
这里如果发现访问者的地址不包含本机ip,那就认为是外部访问,就不符合valid,触发,返回403。
- 效果:
果然拿不到静态资源了。 - 变化:那如果我们想直接访问静态资源呢,右键图片,在新的页面打开(注意,此时是带有referer的),
很遗憾,也不行,因为右键图片,新标签页打开依然是带有referer的。那如果我们想直接访问可以,但是用proxy_pass访问就不行呢?先说一下为什么要这么做,我们知道referer是浏览器加的字段,那如果对方不带referer去访问资源,假如我们需要给这种情况放行呢?这里用到none,很简单,就是用下面的语句替换上面对应配置文件的语句:
valid_referers none 192.168.xxx.xxx;
效果:
虽然右键图片,在新的页面打开是带有referer的,但是复制该图片地址,新建标签粘贴地址,此时的页面是不带referer的,可以看到
下面没有referer,访问成功了,代表放行了。估计下载接口也是这么做的,复制下载链接到标签页访问可以拿到资源,但是用proxy_pass这种带有referer的则会失效。
- 失效返回网页:
上面不是返回403报错嘛,那就将403映射到对应的网页,修改01虚拟机的配置文件:
server {
listen 82;
listen [::]:82;
#root /var/www/web/index;
#index index.html;
server_name localhost;
location / {
proxy_pass http://192.168.yyy.yyy:8080/demo/views/login.html;
#try_files $uri $uri/ =404;
}
location ~*/(js|img|css|layui|assembly) {
valid_referers none 192.168.xxx.xxx;
if ($invalid_referer) {
return 403;
}
root /var/www/web ;
index index.html index.htm;
}
error_page 403 /403.html;
location = /403.html {
root /var/www/error;
}
}
效果:右键图片,新标签打开
中文乱码了,原html里面写的是非法请求~,乱码也无所谓,意思到了。