前两天模仿隔壁博主在介绍页搞了个这玩意:
如果能正确输入博主姓名就会展示真实照片,否则不会显示。
想法很简单,也很好实现。搞个简单的判断语句判断一下就行了:
<img src="假的图片.webp" id="myImage" alt="站长"><br>
<input type="text" id="name" placeholder="站长的真实姓名?">
<button onclick="checkName()">check</button>
<script>
function checkName() {
var nameInput = document.getElementById("name").value;
var image = document.getElementById("myImage");
if (nameInput === "张三") {
image.src = "真的图片.webp";
} else {
image.src = "假的图片.webp";
alert("不对哦~");
}
}
</script>
<style>
#myImage {
width: 30%;
height: auto;
}
</style>
哈希加密
但是这样会有一个严重问题:如果用浏览器F12检查前端原代码,就会发现判断语句if (nameInput === "张三") {
,相当于已经展示“张三”是答案了。
这时候,某个大聪明就会想了:如果把姓名加密就好了,最好还是知道密文而无法破解的那种。诶,哈希值这不就正好用上了嘛。
但据我所知,js好像无法直接将字符串转换哈希值。所以,刚好有个神器——crypto-js。
CryptoJS是一个JavaScript的加解密的工具包。它支持多种算法:
MD5、SHA1、SHA2、SHA3、RIPEMD-160
的哈希散列,以及进行AES、DES、Rabbit、RC4、Triple DES
加解密。(详见官方文档。)
所以,有了CryptoJS就可以简单的改进一下了:把真实姓名转化为哈希值,然后将用户输入的字符串转换为另一个哈希值,两者进行比较就行了。
<img src="假的图片.webp" id="myImage" alt="站长"><br>
<input type="text" id="name" placeholder="站长的真实姓名?">
<button onclick="checkName()">check</button>
<script>
function checkName() {
var nameInput = document.getElementById("name").value;
var image = document.getElementById("myImage");
// 预设哈希值
var realHash = "b0ccdc87a81d6208b25159fbc2db8a07165e6132fbf29cfcc7d08550d4f8786c";
// 计算用户输入的哈希值(SHA256形式)
var inputHash = CryptoJS.SHA256(nameInput).toString();
// 判断
if (inputHash === realHash) {
image.src = "真的图片.jpg";
} else {
image.src = "假的图片.webp";
alert("不对哦~");
}
}
</script>
// 引入crypto-js
<script src="https://source.loneapex.cn/js/crypto-js.min.js"></script>
<style>
#myImage {
width: 30%;
height: auto;
}
</style>
防盗链
那么问题来了,如何做到把真实图片的地址隐藏起来呢?这就要从后端入手了。(要是后端是python我还可以前端请求python拉取参数,但php什么的就不懂了)
众所周知,http请求头中有一个“Referer”的标头,简单来说就是标记来源的。
比如我从”loneapex.cn”点击某个链接跳转到”example.com”,那么访问”example.com”的请求头中就有Referer=loneapex.cn
。
通过判断Referer
的值,这就是网站反盗链的原理了。
回到我写的那个程序上,所以呢,要想不让真实图片被访问,可以在服务器(或者cdn)加一个反盗链,这样直接访问图片就会被拒绝,只有通过loneapex.cn访问才可以(即Referer为loneapex.cn
)
最后
最后我还是想说一下,这仅仅是从前端做的一些加密 什么的。这个问题的根本解决方案是将逻辑转移到后端,前端只负责发送请求,由后端验证输入并返回结果。所以想要更高的安全系数,只有从后端入手了,比如图片动态加载(给前端传base64)防止被抓包。当然,对于我这个小案例而言属实没必要。仅仅是搞着玩玩,图一乐罢了。