基于NodeJS的HTTP server Plus 2:防盗链(referer)

栏目: Node.js · 发布时间: 7年前

内容简介:“盗链” 说白了就是利用别人网站的资源链接放在自己的站点,在未经允许的情况下去获取别人网站里面的图片或者视频等资源,导致资源所有者的网站的流量费用增加或收入减少,为了防止资源链接随意被人盗用的手段被称为 “防盗链”。我们先来模拟一下 “盗链” 场景,在本地启动服务运行文件:hotlinking.html

什么是 “盗链”?

“盗链” 说白了就是利用别人网站的资源链接放在自己的站点,在未经允许的情况下去获取别人网站里面的图片或者视频等资源,导致资源所有者的网站的流量费用增加或收入减少,为了防止资源链接随意被人盗用的手段被称为 “防盗链”。

模拟 “盗链” 场景

我们先来模拟一下 “盗链” 场景,在本地启动服务运行 hotlinking.html 文件,并在文件中盗用百度视频的图片资源,看看效果。

文件:hotlinking.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>盗链</title>
</head>
<body>
    <img src="http://c.hiphotos.baidu.com/video/pic/item/e61190ef76c6a7ef8891a7c9f1faaf51f2de66ad.jpg">
</body>
</html>复制代码

我们通过 http-server 来启动服务器访问 hotlinking.html ,使用 http-server 需全局安装。

http-server install -g

在服务中打开 hotlinking.html 后我们发现图片并不是我们盗用链接的资源,而是变成了下面这张图片。

基于NodeJS的HTTP server Plus 2:防盗链(referer)

这张图用来提醒我们盗用了别人资源,是因为百度的服务器做了防盗链处理,如果所有盗用别人的资源都变成这样,盗用也就没有实际意义了,我们本篇就通过 NodeJS 来实现防盗链处理,用来保护自己站点的资源。

注意:具备防盗链处理的网站的资源链接可以直接通过浏览器地址栏访问,也可以在文件域(file 协议)访问,限制的是在未经允许的情况下其他服务器的访问。

NodeJS 服务器实现防盗链

1、模拟两个域名

在本地的 hosts 文件中加入两个域名:

127.0.0.1 panda.com

shen.com

2、准备图片资源

在根目录创建文件夹 public 并存入两张图片, success.png 是正常请求的图片资源, error.png 是经过防盗链处理后返回的图片资源,两张图片如下。

正常返回的图片资源 success.png:

基于NodeJS的HTTP server Plus 2:防盗链(referer)

防盗链处理后返回的图片资源 error.png:

基于NodeJS的HTTP server Plus 2:防盗链(referer)

3、页面 index.html

在页面当中通过 img 标签分别访问shen.com、panda.com 和localhost 域下的 success.png 文件。

文件:index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>盗链</title>
</head>
<body>
    <img src="http://panda.com:3000/success.png">
    <img src="http://shen.com:3000/success.png">
    <img src="http://localhost:3000/success.png">
</body>
</html>复制代码

4、服务端 server.js

在写服务端代码之前需要介绍两个重要的请求头:

  • host:资源所在的域
  • referer:请求来源的域

其实资源防盗就是设置白名单,通过检测 referer 是否在白名单中,如果在则正常返回资源,不存在则返回经过防盗链处理的资源。

注意:referer 请求头在地址栏输入地址时发送的请求是不存在的(如请求 index.html 页面),在旧版本的 HTTP 协议中 referer 的写法为 referered ,所以为了兼容旧版本协议应该做兼容处理。

文件:server.js

// 引入依赖
const http = require("http");
const url = require("url");
const path = require("path");
const fs = require("mz/fs");

const server = http.createServer(responseImages); // 创建服务器
let static = path.resolve(__dirname, "public"); // 静态资源目录
let whiteList = ["shen.com"]; // 白名单

async function responseImages(req, res) {
    // 解析 url 中的文件目录处理成绝对路径
    let p = path.join(static, url.parse(req.url).pathname);

    // 检测文件路径是否合法,不合法直接返回 Not Found
    let isExist = await fs.exists(p);

    if (isExist) {
        // 获取 referer
        let refer = req.headers["referer"] || req.headers["referered"];

        // 存在 referer 继续检测
        if (refer) {
            // 请求资源存在 referer,做防盗链处理
            let referHost = url.parse(refer).hostname;
            let host = req.headers["host"].split(":")[0];

            // 当访问源的域和资源所在的域不是同一个域,做防盗链处理
            if (referHost !== host) {
                let isInWhiteList = whiteList.includes(refer);
                p = isInWhiteList ? p : path.join(static, "error.png");
            }
        }

        // 第一次访问请求页面 index.html,不存在 referer,将静态资源返回
        // 第二次访问请求图片资源,如果 referer 和资源所本就是同一个域,直接将资源返回
        fs.createReadStream(p).pipe(res);
    } else {
        res.statusCode = 404;
        res.end("Not Found");
    }
}

server.listen(3000, () => {
    console.log("server start 3000");
});复制代码

其实上面的服务器是 shen.companda.comlocalhost 所共用的,只是通过不同的域名访问。

启动服务器,然后通过 localhost:3000 访问,此时由于与 shen.companda.com 为不同域,所以只有第三张图片返回 success.png

通过 shen.com:3000 访问,由于存在白名单中,所以三张图片都返回 success.png

通过 panda.com:3000 访问,由于 shen.com 在不同域,所以没有返回 success.png

无论通过 shen.com 还是 panda.com 访问 localhost 的资源都是在同域的,所以都能获取到。

总结

在上面我们利用本地服务实现了一个最基本的防盗链,思路就是 referer 与资源同域,正常返回,不同域检测白名单,在真实的开发场景可能会更细化,更复杂一些,其实整个防盗链实现的核心就是利用 HTTP 的 refererhost 请求头做检测,希望通过本篇的学习,大家可以对资源防盗链有所了解,并在后面开发类似功能时提供思路。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Mastering Regular Expressions, Second Edition

Mastering Regular Expressions, Second Edition

Jeffrey E F Friedl / O'Reilly Media / 2002-07-15 / USD 39.95

Regular expressions are an extremely powerful tool for manipulating text and data. They have spread like wildfire in recent years, now offered as standard features in Perl, Java, VB.NET and C# (and an......一起来看看 《Mastering Regular Expressions, Second Edition》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具