小白教程 AList嵌入动态验证码实现引流

之前不是在博客写了一篇文章嘛,写了一个关于Alist动态验证码的功能,访问Alist必须进行验证后才能进行访问,然后这个可能对小白不太友好,这里我写篇详尽文章教大家如何使用AList嵌入动态验证码

准备工作

  • 一台国内服务器
  • 已备案域名
  • 微信订阅号一个

环境准备

搭建一个Web服务器环境是创建和维护网站的基础步骤。对于有经验的开发者来说,这个过程可能已经非常熟悉了。但对于那些刚开始接触建站的朋友,建议您先去看一下如何建站

安装Node.js

Node.js是一个开源、跨平台的JavaScript运行时环境,它允许开发者在服务器端运行JavaScript代码,本程序后端就是基于Node.js编写的,如果您不了解Node.js 那您更应该仔细看这部分内容了

以我的 Debian系 主机环境为例

1,下载安装Node.js (18+版本均可)

下载地址:https://nodejs.cn/download/

或者直接执行如下命令

wget https://npmmirror.com/mirrors/node/v20.18.0/node-v20.18.0-linux-x64.tar.xz

下载完成后将 node-v20.18.0-linux-x64.tar.xz 解压到当前文件夹,会得到 node-v20.18.0-linux-x64

node-v20.18.0-linux-x64文件夹移动到/usr/local/node 目录中,并重命名为node

2,配置 Node.js 环境

编辑/etc/profile 文件

最底部添加如下内容

export NODE_HOME=/usr/local/node
export PATH=$NODE_HOME/bin:$PATH

保存之后执行 source /etc/profile 使其生效。

3,配置镜像加速

由于某些原因, npmjs.com 在国内的访问速度很不稳定。 所以我们可以考虑用国内的镜像网站地址替换,执行如下命令,配置为国内镜像源

npm config set registry https://registry.npmmirror.com
4,克隆仓库

我将这个项目的代码上传到了GitHub,可直接从github获取

地址:Alist_Dynamic_verification: Alist AList嵌入动态验证码工具 (github.com)

5,安装依赖
cd Alist_Dynamic_verification
npm install
6,配置微信订阅号相关信息

编辑 .env 配置相关信息(后面配置也可以)

WECHAT_APPID=
WECHAT_SECRET=
WECHAT_TOKEN=
ENCODING_AES_KEY=
PORT=4000 # 后端运行端口,对接微信
VERIFY_PORT=4001 # 验证接口的端口,对接前端验证验证码用的
# 端口可以不定义 默认就是上面那俩
7,启动
node run serve
8,配置反向代理

因为微信公众号强制要求使用HTTP/HTTPS端口,这里以Nginx为例,配置反向代理

我这里用了两个域名,例如;

  • test.example.com(用于对接微信公众平台)
  • verify.example.com(用于验证验证码的)

nginx配置文件如下

test.example.com

server {
    listen 80;
    server_name test.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name test.example.com;
    # SSL 配置
    ssl_certificate /etc/ssl/certs/certificate.crt;
    ssl_certificate_key /etc/ssl/private/private_key.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    
    location / {
        proxy_pass http://localhost:4000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

verify.example.com

server {
    listen 80;
    server_name verify.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name verify.example.com;
    # SSL 配置
    ssl_certificate /etc/ssl/certs/certificate.crt;
    ssl_certificate_key /etc/ssl/private/private_key.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    
    location / {
        proxy_pass http://localhost:4001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

二合一配置

server {
    listen 80;
    server_name test.example.com;

    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl;
    server_name test.example.com;
    
    ssl_certificate /etc/ssl/certs/certificate.crt;
    ssl_certificate_key /etc/ssl/private/private_key.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        proxy_pass http://localhost:4000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    location /verify/ {  # 将 /verify/ 路径的请求转发到 4001 端口
        proxy_pass http://localhost:4001/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
9、公众号配置

如上图所示,服务器地址(URL) 配置为 http://你的域名.com/eventCall/,并配置好其他参数即可

10,开机自动运行(systemd)

/etc/systemd/system/目录创建一个service文件, 定义如下内容

[Unit]
Description=Alist_Dynamic_verification
After=network.target

[Service]
ExecStart=/usr/local/node/bin/npm run serve # npm全路径,按照你的安装位置修改
WorkingDirectory= # 你的项目目录
# Environment=NODE_ENV=production
Restart=always

[Install]
WantedBy=multi-user.target

完了 daemon-reload一下 enable --now 运行服务就可以了

Alist嵌入代码
<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>
评论区
头像
    头像
    小趴菜
         IP属地:云南省 昆明市 中国电信

    大佬,求出个宝塔面板安装这个的教程

文章目录