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

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

内容简介:“盗链” 说白了就是利用别人网站的资源链接放在自己的站点,在未经允许的情况下去获取别人网站里面的图片或者视频等资源,导致资源所有者的网站的流量费用增加或收入减少,为了防止资源链接随意被人盗用的手段被称为 “防盗链”。我们先来模拟一下 “盗链” 场景,在本地启动服务运行文件: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 请求头做检测,希望通过本篇的学习,大家可以对资源防盗链有所了解,并在后面开发类似功能时提供思路。


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

查看所有标签

猜你喜欢:

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

LaTeX入门

LaTeX入门

刘海洋 / 电子工业出版社 / 2013-6-1 / CNY 79.00

LaTeX 已经成为国际上数学、物理、计算机等科技领域专业排版的实际标准,其他领域(化学、生物、工程、语言学等)也有大量用户。本书内容取材广泛,涵盖了正文组织、自动化工具、数学公式、图表制作、幻灯片演示、错误处理等方面。考虑到LaTeX 也是不断进化的,本书从数以千计的LaTeX 工具宏包中进行甄选,选择较新而且实用的版本来讲解排版技巧。 为了方便读者的学习,本书给出了大量的实例和一定量的习......一起来看看 《LaTeX入门》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具