用Express做一个图片简易防盗链

最近做的一个主管安排的项目,给一个系统多增加一套前端模板,这个本身不难,由于算法那边不能提供数据,我随便复制的网上图片链接,发现有些图片不能正常显示,后来知道有些图片加了“防盗链”,这让我马上想到了以前遇到的http请求头中的referer属性,这个消息头记录了本网站的一些资源请求是来自哪个网站,如果利用这个referer的判断,就可以实现过滤。

代码:

var express = require('express');
var app = express();
var fs = require('fs');
// 设置模板路径,默认为./views
// app.set('views', path.join('views'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

app.get('/public/*',
    function (req, res, next) {
        var referer = req.headers.referer;
        console.log(referer);
        if (referer && referer.indexOf('localhost1') <= 0) {
            try {
                fs.readFile("./views/no.png", function (err, data) {
                    console.log("no");
                    res.writeHead(200, {"Content-type": "image/jpg"});
                    console.log(err);
                    // console.log(data);
                    res.end(data);
                });
            } catch (err) {
                console.log(err);
            }
        } else {
            try {
                fs.readFile("./views/a.jpg", function (err, data) {
                    console.log("normal");
                    res.writeHead(200, {"Content-type": "image/jpg"});
                    // console.log(data);
                    res.end(data);
                });
            } catch (err) {
                console.log(err);
            }
        }
    });
app.get('/', function (req, res) {
    res.render('index', {helloWorld: 'hello,world'});
});

app.listen(3000, function () {
    console.log('app listen at 3000');
});

referer是一个网站中某个资源的请求才会带的属性,如果是直接访问图片的这个地址,是不带referer的,所以
这里写图片描述
这里判断的时候,先要判断referer存在,再判断是不是从某域发过来的请求,因为我们直接访问地址的时候是想看到图片结果的,只是一些网站引用我们的图片链接时我们加以屏蔽。

还可以以中间件的形式:

var express = require('express');
var app = express();
var fs = require('fs');
// 设置模板路径,默认为./views
// app.set('views', path.join('views'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

function sss (req, res, next) {
    var referer = req.headers.referer;
    console.log(referer);
    // console.log(referer.indexOf('localhost3'));
    if (referer && referer.indexOf('localhost1') >= 0) {
        next();
    } else {
        // console.log(res);
        console.log(1);
        // res.state(500).send('盗链图片来自:<a href="xxxxx"></a>');
        res.send('盗链图片来自:<a href="xxxxx"></a>');
        return false;
    }
}

app.get('/public/*',
    sss,
    function (req,res,next) {
    console.log(234234);
        try {
            fs.readFile("./views/a.jpg", function (err, data) {
                res.writeHead(200, {"Content-type": "image/jpg"});
                console.log(err);
                // console.log(data);
                res.end(data);
            });
        }catch (err) {
            console.log(err);
        }
});
app.get('/', function(req, res) {
    console.log(10);
    res.render('index', { helloWorld: 'hello,world' });
});

app.listen(3000, function() {
    console.log('app listen at 3000');
});

当然破解这种写法的防盗链也很简单,用中间服务器伪造消息头就行了。

posted @ 2018-04-13 10:56  Lawliet__zmz  阅读(313)  评论(0编辑  收藏  举报