最近利用ALists创建了个网盘资源站,想着如何增加个动态验证码进行验证后才能进行访问下载,动态获取验证码,使用了禁止打开控制台校验等方式减少绕过几率,现在分享给大家。

NodeJS后端代码

利用json存储验证码数据,并且用户无法重复获取验证码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
require('dotenv').config();
const express = require('express');
const wechat = require('wechat');
const fs = require('fs');
const axios = require('axios');
const cors = require('cors');

const app = express();
const dbPath = './codes.json';

// CORS 中间件
app.use(cors({
origin: function (origin, callback) {
if (!origin || origin.endsWith('*')) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
}));

app.use(express.json());

// 读取 JSON 数据
function readData() {
if (!fs.existsSync(dbPath)) {
fs.writeFileSync(dbPath, JSON.stringify({}));
}
return JSON.parse(fs.readFileSync(dbPath));
}

// 保存 JSON 数据
function saveData(data) {
fs.writeFileSync(dbPath, JSON.stringify(data));
}

// 处理微信请求
app.use('/', wechat({
token: process.env.WECHAT_TOKEN,
appid: process.env.WECHAT_APPID,
encodingAESKey: process.env.ENCODING_AES_KEY,
checkSignature: false
}, async (req, res, next) => {
const { FromUserName, Content } = req.weixin;

// 处理“验证码”请求
if (Content.trim() === '验证码') {
const userKey = FromUserName;
const data = readData();

// 检查是否已经生成过验证码
const userData = data[userKey];
const today = new Date().toISOString().split('T')[0];

if (userData && userData.date === today) {
return res.reply(`今天已经获取过验证码了, 您的验证码是: ${userData.code}`);
}

// 生成新的验证码
const newCode = Math.floor(100000 + Math.random() * 900000).toString(); // 生成6位随机数字
const timestamp = Date.now();

// 插入或更新验证码
data[userKey] = {
code: newCode,
date: today,
timestamp: timestamp
};
saveData(data);

return res.reply(`您的验证码是: ${newCode}(12小时内有效)`);
}
res.reply('未知指令,请回复“验证码”获取验证码');
}));

// 验证验证码的接口
app.post('/verify', (req, res) => {
const { code } = req.body;
const data = readData();

const isValid = Object.values(data).some(userData => userData.code === code);

if (isValid) {
return res.json({ success: true, message: '验证码有效' });
} else {
return res.json({ success: false, message: '验证码无效或已过期' });
}
});

// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server listening at http://localhost:${PORT}`);
});

前端代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<script disable-devtool-auto src='https://cdn.jsdelivr.net/npm/disable-devtool'></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>

<script>
document.addEventListener('keydown', function(event) {
if (event.key === 'F12' || (event.ctrlKey && event.shiftKey && ['I', 'J', 'C'].includes(event.key.toUpperCase()))) {
event.preventDefault();
}
});

document.addEventListener("DOMContentLoaded", function() {
promptPassword("success", "请输入验证码以继续访问");
});

// 验证验证码函数
function validateCaptcha(captcha) {
const xhr = new XMLHttpRequest();
xhr.open("POST", "验证接口, true);
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
try {
const response = JSON.parse(xhr.responseText);
if (xhr.status === 200 && response.code === 200) {
welcomeUser();
} else {
swal("错误", response.msg || "验证码错误,请重试", "error").then(() => {
promptPassword("error", "请重新输入验证码");
});
}
} catch (e) {
console.error("JSON 解析错误:", e);
swal("错误", "响应格式不正确,请稍后重试", "error").then(() => {
promptPassword("error", "请重新输入验证码");
});
}
}
};

xhr.send(JSON.stringify({ code: captcha }));
}

// 提示输入验证码的函数
function promptPassword(icon, title) {
swal({
title: title,
text: "请确认您已获取正确的验证码。请点击下方按钮关注我们的微信公众号以获取验证码。",
closeOnClickOutside: false,
icon: icon,
buttons: {
confirm: {
text: "确认提交",
value: "confirm",
className: "custom-swal-button swal-button--confirm"
},
getCode: {
text: "微信公众号",
value: "get_code",
className: "custom-swal-button swal-button--copy"
}
},
content: {
element: "input",
attributes: {
placeholder: "请输入验证码",
type: "text",
style: "width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px;"
}
}
})
.then((value) => {
if (value === '') {
promptPassword("warning", "请输入正确的验证码");
} else if (value === "get_code") {
showWeChatCode();
} else if (!/^\d{6}$/.test(value)) {
promptPassword("warning", "验证码格式不正确,请输入6位数字");
} else {
validateCaptcha(value);
}
});
}

// 显示微信公众号二维码
function showWeChatCode() {
swal({
title: "关注微信公众号获取验证码",
text: "请扫描以下二维码关注我们的微信公众号以获取验证码。",
icon: "info",
closeOnClickOutside: false,
content: {
element: "img",
attributes: {
src: "公众号图片",
style: "width: 100%; height: auto; border-radius: 4px;"
}
},
buttons: {
confirm: {
text: "返回输入",
value: "confirm",
className: "custom-swal-button swal-button--confirm"
}
}
}).then(() => {
promptPassword("info", "请输入验证码以继续访问");
});
}

// 欢迎用户函数
function welcomeUser() {
swal("欢迎!", {
icon: "success",
buttons: false,
timer: 1000, //1秒后自动消失
});
}


// 防止查看页面源代码
window.onbeforeunload = function() {
return "您确定要离开此页面吗?";
};

// 检测并阻止右键菜单
window.addEventListener('contextmenu', function(event) {
event.preventDefault();
}, false);

// 检测并阻止选中文本
window.addEventListener('selectstart', function(event) {
event.preventDefault();
}, false);
</script>

效果图