什么是盗链和防盗链?
“盗链” 说白了就是利用别人网站的资源链接放在自己的站点,在未经允许的情况下去获取别人网站里面的图片或者视频等资源,导致资源所有者的网站的流量费用增加或收入减少,为了防止资源链接随意被人盗用的手段被称为 “防盗链”。
防盗链如何实现呢?
大多数站点的策略很简单: 判断request请求头的referer是否来源于本站。若不是,拒绝访问真实图片。
而我们知道: 请求头是来自于客户端,是可伪造的。
场景
一些网上寻找的图片视频资源地址,在浏览器地址框里输入是可以查看到。但是用到了项目上就显示不出来,报403错误。这是因为,这些资源地址设置了防盗链措施。
浏览器请求时,请求头的Referer为空,所以可以请求到资源。
但在项目上,请求头的Referer不为空(来源地址),对方的服务器对Referer做了限制,因此请求不到数据。
那么,我们伪造一个正确的referer来访问不就行了?
下面给出简单Referer限制的防盗链解决办法
nodejs服务器做防盗链资源中转
整个业务逻辑大概像这样:
- 自己的服务器后台接受带目标图片url参数的请求
- 伪造referer请求目标图片
- 把请求到的数据作为response返回
express 解决方法
const express = require('express');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const app = express();
//根据不同的功能 划分模块 (动态)
app.use(cookieParser());
app.use(bodyParser.json());
app.use('/user',require('./routers/index.js'));
app.listen(3000,(res,req)=>{
console.log('Node app start at port 3000');
});
var express = require('express');
var router = express.Router();
var request = require('request');
var router = express.Router();
router.get('/api', function(req, res, next) {
var url=req.query.url;
var options = {
method: "GET",
url:url,
headers:{
"Referer": request.host
}
};
request(options).pipe(res);
});
module.exports = router;
设置了防盗链的资源地址:https://vfx.mtime.cn/Video/2020/01/19/mp4/200119111202176577_1080.mp4
请求资源示例:
http://localhost:3000/user/api?url=https://vfx.mtime.cn/Video/2020/01/19/mp4/200119111202176577_1080.mp4
koa2 解决方法
const Koa = require('koa')
const app = new Koa()
const router = require('./routes/referer');
app.use(router.routes());
app.listen(3000)
const Router = require('koa-router') // koa 路由中间件
const router = new Router(); // 实例化路由
const request = require('request');
router.get('/api', async(ctx, next) => {
var url=ctx.request.query.url;
var options = {
method: "GET",
url:url,
headers:{
"Referer": request.host
}
};
const PassThrough = require('stream').PassThrough;
ctx.body = request(options)
.on('response', response => {
Object.keys(response.headers).forEach((key) => {
// if ('content-length' === key) return;
if ('transfer-encoding' === key) return;
ctx.set(key, response.headers[key]);
});
})
.on('error', ctx.onerror)
.pipe(PassThrough())
});
module.exports = router;
设置了防盗链的资源地址:https://vfx.mtime.cn/Video/2020/01/19/mp4/200119111202176577_1080.mp4
请求资源示例:
http://localhost:3000/api?url=https://vfx.mtime.cn/Video/2020/01/19/mp4/200119111202176577_1080.mp4