基于NodeJS的HTTP server Plus 2:防盗链(referer)
什么是 “盗链”?
“盗链” 说白了就是利用别人网站的资源链接放在自己的站点,在未经允许的情况下去获取别人网站里面的图片或者视频等资源,导致资源所有者的网站的流量费用增加或收入减少,为了防止资源链接随意被人盗用的手段被称为 “防盗链”。
模拟 “盗链” 场景
我们先来模拟一下 “盗链” 场景,在本地启动服务运行 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 来实现防盗链处理,用来保护自己站点的资源。
NodeJS 服务器实现防盗链
1、模拟两个域名
在本地的 hosts 文件中加入两个域名:
127.0.0.1 panda.com
127.0.0.1 shen.com
2、准备图片资源
在根目录创建文件夹 public
并存入两张图片,success.png
是正常请求的图片资源,error.png
是经过防盗链处理后返回的图片资源,两张图片如下。
正常返回的图片资源 success.png:
防盗链处理后返回的图片资源 error.png:
3、页面 index.html
在页面当中通过 img
标签分别访问 shen.com、panda.com 和 localhost 域下的 success.png
文件。
<!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
的写法为 referered
,所以为了兼容旧版本协议应该做兼容处理。
// 引入依赖
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 Foundlet isExist = await fs.exists(p);if (isExist) {// 获取 refererlet 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.com、panda.com 和 localhost 所共用的,只是通过不同的域名访问。
启动服务器,然后通过 localhost:3000 访问,此时由于与 shen.com 和 panda.com 为不同域,所以只有第三张图片返回 success.png
。
通过 shen.com:3000 访问,由于存在白名单中,所以三张图片都返回 success.png
。
通过 panda.com:3000 访问,由于 shen.com 在不同域,所以没有返回 success.png
。
无论通过 shen.com 还是 panda.com 访问 localhost 的资源都是在同域的,所以都能获取到。
总结
在上面我们利用本地服务实现了一个最基本的防盗链,思路就是 referer
与资源同域,正常返回,不同域检测白名单,在真实的开发场景可能会更细化,更复杂一些,其实整个防盗链实现的核心就是利用 HTTP 的 referer
和 host
请求头做检测,希望通过本篇的学习,大家可以对资源防盗链有所了解,并在后面开发类似功能时提供思路。
基于NodeJS的HTTP server Plus 2:防盗链(referer)相关推荐
- html设置referer防盗链,referer与防盗链
referer是什么 referer 中文意思是:参照页面,引用页. 下图直观感受,(づ ̄ 3 ̄)づ image 直接在浏览器中输入url地址来直接访问图片/js/css等资源时是没有referer的 ...
- 单机十万并发HLS直播服务器的防盗链技术
单机十万并发HLS直播服务器的防盗链技术 本文主要介绍基于HLS直播服务器的十万并发防盗链实现 录制切片服务器 HTTP 服务器 (nginx) LuaLib 录制切片服务器 录制切片服务器负责把直播 ...
- 基于Nodejs的前端灰度发布方案_20190228
基于Nodejs的前端灰度发布方案 1. 灰度发布和A/B测试简介 灰度发布 将某个功能灰度发布(逐渐放量)给特定线上人群,避免新功能全量上线带来的风险. 上面的图可以通过两个方面来理解: 蓝色实线和 ...
- 基于ASP.NET+SQL Server实现(Web)企业进销存管理系统【100010296】
企业进销存管理系统的设计和实现 一.摘要 进销存管理是现代企业生产经营中的重要环节,是完成企业资源配置的重要管理工作,对企业生产经营效率的最大化发挥着重要作用.本文以我国中小企业的进销存管理为研究 ...
- node php聊天室,利用socket.io实现多人聊天室(基于Nodejs)
利用socket.io实现多人聊天室(基于Nodejs) socket.io简介 在Html5中存在着这样的一个新特性,引入了websocket,关于websocket的内部实现原理可以看这篇文章,这 ...
- 基于nodejs爬虫程序下载
node-crawler 一个基于nodejs的网站采集服务器 可部署在任何服务器上远程调用 DEMO 发送请求 run npm dev POST: /scan {"url": & ...
- 搭建基于 nodejs 的 MQTT 服务器
创建服务端 1.先从初始化一个 package.json 开始. npm init 2.安装 mqtt 服务器必要依赖项 mosca mqtt npm install mosca mqtt 3.根目录 ...
- Sequelize 4.43.0 发布,基于 Nodejs 的异步 ORM 框架
Sequelize 4.43.0 发布了,Sequelize 是一款基于 Nodejs 的异步 ORM 框架,它同时支持 PostgreSQL.MySQL.SQLite 和 MSSQL 多种数据库,很 ...
- 基于群集的Hyper-v Server副本
基于群集的Hyper-v Server副本 前面的博文中和大家聊了Hyper-v副本,相信大家对Hyper-v副本已经有了一个大致了解!今天我们就来给大家介绍一下基于群集的Hyper-v Replic ...
最新文章
- JMessage Android 端开发详解
- 关于一个枚举IE表单的DLL,编译无错,但是得不到想到的结果。
- 解决在非Activity中使用startActivity
- 【转】1.SharePoint服务器端对象模型 之 对象模型概述(Part 1)
- 10分钟教会你Apache Shiro
- python循环绘制六角星_《Python游戏趣味编程》 第3章 美丽的圆圈画
- Oracle 10g 高级安装图文教程(一)
- Java程序员校招蚂蚁金服,大专生出身,做Java程序员真的没有春天吗
- QTP引用外部脚本路径的设定(二)left函数的使用
- HTTP请求报文分析
- 阿文PPT教程视频课程2019送PPT模板 我懂个P
- python wps et_使用Python操作XLS文件(wps中叫et)
- html页面背景图片不够大怎么办,Word背景图片不够大怎么办
- 解决Chrome浏览器主页被hao123、360和2345篡改简单有效方法
- Python网络爬虫反爬破解策略实战
- LLS2000 智能多通道信号控制采集器
- 自协方差函数的Matlab实现
- JavaScript object移除
- 弄清楚这个三角关系,工作效率提高50%
- 如何解决青年大学习的复制粘贴问题???
热门文章
- EF ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象...
- Windows程序中的Lib和Dll文件
- # [银联复赛]-整数对:数论
- sublime与python交互
- 【洛谷习题】尼克的任务
- HDU——1272小希的迷宫(并查集+拓扑排序)
- WinForm里ListBox实现加入项目,并且排序。
- DeepFaceLab报错,CUDA driver is insufficient 解决方法!
- 【回顾】推荐系统工程师技能树
- ICML 2019 | 强化学习用于推荐系统,蚂蚁金服提出生成对抗用户模型(附论文下载链接)...