hCaptcha 人机验证集成文档

hCaptcha 人机验证集成文档

hCaptcha 人机验证集成文档

📋 项目概述

本项目在登录、注册、忘记密码三个核心页面集成了 hCaptcha 人机验证,防止机器人攻击和恶意注册。

✅ 已实现的功能

1. 登录页面验证

  • hCaptcha 验证码

  • 登录次数限制:失败 5 次后冻结 24 小时

  • 自动解封:24 小时后自动重置失败次数

2. 注册页面验证

  • hCaptcha 验证码

  • 邮箱验证码(6位数字)

  • 发送次数限制:每天最多 5 次

3. 忘记密码验证

  • hCaptcha 验证码

  • 邮箱验证码(6位数字)

  • 发送次数限制:每天最多 5 次

  • 验证码有效期:10 分钟

🔧 技术实现

后端实现

1. 统一验证工具

文件:src/utils/hcaptcha.ts


const hcaptcha = require('hcaptcha');



export async function verify(token: string): Promise<{ success: boolean; message?: string }> {

    const secretKey = process.env.HCAPTCHA_SECRET_KEY;

    

    // 未配置密钥时返回错误

    if (!secretKey) {

        return {

            success: false,

            message: 'hCaptcha 密钥未配置'

        };

    }

    

    try {

        // 调用 hcaptcha 包的 verify 方法

        const result = await hcaptcha.verify(secretKey, token);

        

        return {

            success: result.success === true,

            message: result.message || result['error-codes']?.join(', ')

        };

    } catch (error: any) {

        return {

            success: false,

            message: error.message || '验证失败'

        };

    }

}

2. 登录接口

文件:src/routes/login.ts

关键代码:


app.post('/login', async (request, reply) => {

    const { email, password, hcaptcha_token } = request.body;

    

    // 验证 hCaptcha token

    if (!hcaptcha_token || hcaptcha_token === 'no-captcha') {

        return reply.code(400).send({

            code: 400,

            message: '请完成验证码'

        });

    }

    

    const verifyResult = await verifyCaptcha(hcaptcha_token);

    if (!verifyResult.success) {

        return reply.code(400).send({

            code: 400,

            message: '验证码验证失败'

        });

    }

    

    // 继续登录验证...

});

验证逻辑:

  1. 检查 hCaptcha token 是否存在

  2. 调用 hCaptcha 验证服务

  3. 验证登录失败次数(5 次后冻结 24 小时)

  4. 密码验证

  5. 登录成功或返回错误

3. 注册接口

文件:src/routes/register.ts

关键代码:


app.post('/register', async (request, reply) => {

    const { username, password, email, code, hcaptcha_token } = request.body;

    

    // 验证 hCaptcha

    if (!hcaptcha_token || hcaptcha_token === 'no-captcha') {

        return reply.code(400).send({

            code: 400,

            message: '请完成验证码'

        });

    }

    

    const verifyResult = await verifyCaptcha(hcaptcha_token);

    if (!verifyResult.success) {

        return reply.code(400).send({

            code: 400,

            message: '验证码验证失败'

        });

    }

    

    // 验证邮箱验证码

    const db_code = await collection("web_user_code").findOne({ email, code });

    // ...

});

发送验证码:


app.post('/register/sendCode', async (request, reply) => {

    // 1. 验证邮箱格式

    // 2. 检查每天发送次数(最多 5 次)

    // 3. 检查邮箱是否已存在

    // 4. 生成 6 位验证码

    // 5. 发送邮件

    // 6. 保存验证码到数据库

});

4. 忘记密码接口

文件:src/routes/login.ts

关键代码:


app.post('/forget/sendCode', async (request, reply) => {

    // 1. 验证邮箱格式

    // 2. 检查邮箱是否存在

    // 3. 检查每天发送次数(最多 5 次)

    // 4. 生成 6 位验证码

    // 5. 发送邮件

});



app.post('/forget', async (request, reply) => {

    // 1. 验证 hCaptcha token

    // 2. 验证邮箱验证码

    // 3. 检查验证码是否过期(10 分钟)

    // 4. 更新密码

    // 5. 删除验证码记录

});

前端实现

1. 引入 hCaptcha 脚本

所有页面都需要在 <head> 中添加:


<script src="https://js.hcaptcha.com/1/api.js" async defer></script>

2. 添加验证码组件

在表单中添加:


<!-- hCaptcha 验证码 -->

<div class="flex justify-center py-2">

    <div class="h-captcha" data-sitekey="{{hcaptcha_site_key}}"></div>

</div>

3. 表单提交逻辑

在 JavaScript 中:


// 获取 hCaptcha token

const hcaptchaToken = hcaptcha.getResponse();



// 检查验证码是否完成

if (!hcaptchaToken) {

    showErrorToast('请完成验证码');

    return;

}



// 发送请求,带上 token

fetch('/login', {

    method: 'POST',

    body: JSON.stringify({

        email,

        password,

        hcaptcha_token: hcaptchaToken

    })

});



// 成功后重置验证码

if (typeof hcaptcha !== 'undefined') {

    hcaptcha.reset();

}

📁 文件结构


src/

├── routes/

│   ├── login.ts          # 登录 + 忘记密码路由

│   └── register.ts        # 注册路由

├── utils/

│   └── hcaptcha.ts        # hCaptcha 验证工具

views/

├── login.hbs              # 登录页面

├── register.hbs           # 注册页面

└── forget.hbs             # 忘记密码页面

⚙️ 配置说明

环境变量

文件:.env


# hCaptcha 配置

HCAPTCHA_SITE_KEY=your_site_key_here      # 前端显示密钥

HCAPTCHA_SECRET_KEY=your_secret_key_here   # 后端验证密钥

获取密钥步骤

  1. 访问 https://www.hcaptcha.com/

  2. 注册账号并登录

  3. 创建站点(选择验证码类型)

  4. 获取密钥:

    • Site Key - 用于前端(公开)

    • Secret Key - 用于后端(保密)

本地测试

开发环境如果是 localhost,会显示警告,但不影响使用。

如需移除警告,可在 hCaptcha 后台:

  • 添加 localhost127.0.0.1 到允许的域名

  • 或使用测试密钥(仅用于开发)

🔐 安全特性

1. 多层验证

  • hCaptcha:防止机器人自动化

  • 邮箱验证码:确认邮箱所有权

  • 登录限制:防止暴力破解

2. 发送限制

  • 邮箱验证码:每天最多 5 次

  • 防止恶意刷取验证码

3. 验证码过期

  • 邮箱验证码:10 分钟有效

  • 提高安全性

4. 账户保护

  • 登录失败 5 次:冻结 24 小时

  • 防止暴力破解

📦 安装的依赖


pnpm add hcaptcha

版本: [email protected]

🚀 使用流程

登录流程

  1. 用户输入邮箱密码

  2. 完成 hCaptcha 验证

  3. 提交 → 后端验证 token

  4. 验证登录失败次数

  5. 密码验证

  6. 登录成功

注册流程

  1. 用户填写注册信息

  2. 输入邮箱,点击"发送验证码"

  3. 接收邮件,输入验证码

  4. 完成 hCaptcha 验证

  5. 提交 → 后端同时验证邮箱验证码和 hCaptcha token

  6. 注册成功

忘记密码流程

  1. 输入邮箱,点击"发送验证码"

  2. 接收邮件,输入验证码

  3. 输入新密码

  4. 完成 hCaptcha 验证

  5. 提交 → 后端验证所有信息

  6. 更新密码成功

🎯 拓展方案

1. Google reCAPTCHA v3

特点:

  • 完全无感,用户体验最好

  • Google 提供,技术成熟

  • 免费,无使用限制

集成方式:


// 后端验证

const response = await fetch(`https://www.google.com/recaptcha/api/siteverify?secret=${SECRET_KEY}&response=${token}`);

const data = await response.json();

前端集成:


<script src="https://www.google.com/recaptcha/api.js?render=SITE_KEY"></script>

对比:

  • ✅ 用户体验:最好(无感)

  • ✅ 免费额度:无限

  • ✅ 技术成熟:Google

  • ❌ 国内访问:可能较慢

2. Cloudflare Turnstile

特点:

  • 免费且无需费用

  • 用户体验好(轻量级)

  • 技术先进(Cloudflare 提供)

集成方式:


<!-- 前端 -->

<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>

<div class="cf-turnstile" data-sitekey="SITE_KEY"></div>



<!-- 后端 -->

const response = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {

    method: 'POST',

    body: JSON.stringify({

        secret: SECRET_KEY,

        response: token

    })

});

对比:

  • ✅ 完全免费

  • ✅ 体验好

  • ✅ 性能优秀

  • ✅ 配置简单

3. Microsoft Azure Bot Protection

特点:

  • 企业级安全

  • 与 Azure AD 集成

  • 需要付费计划

适用场景:

  • 企业应用

  • 需要与 Microsoft 生态系统集成

  • 高安全要求

4. 自建图形验证码

实现方式:

  • 生成随机图片(如数学题、文字识别)

  • 服务端存储答案

  • 客户端输入验证

优点:

  • 完全自主控制

  • 无第三方依赖

  • 无费用

缺点:

  • 用户体验较差

  • 安全性较低(容易被破解)

  • 维护成本高

5. 短信验证码

特点:

  • 双重验证:邮箱 + 手机

  • 安全性高

  • 需要 SMS 服务商(如 Twilio、阿里云)

适用场景:

  • 金融、支付类应用

  • 高安全要求

  • 需要手机号认证

6. 多重验证(MFA)

组合方式:


// 1. hCaptcha - 防止机器人

// 2. 邮箱验证码 - 确认邮箱

// 3. 短信验证码 - 双重认证

// 4. TOTP(如 Google Authenticator)- 动态密码

📊 各方案对比

| 方案 | 免费 | 用户体验 | 安全性 | 国内可用 | 推荐度 |

|------|------|---------|--------|---------|--------|

| hCaptcha | ✅ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |

| reCAPTCHA v3 | ✅ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |

| Turnstile | ✅ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |

| 自建验证码 | ✅ | ⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ |

| 短信验证码 | ❌ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |

| MFA | ✅ | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |

💡 推荐方案

当前实现

hCaptcha - 已集成,功能完善,适合大多数场景

如果追求更好体验

Cloudflare Turnstile - 免费、无感、性能好

如果需要更高安全

reCAPTCHA v3 + 短信验证 - 多重验证,企业级安全

📝 总结

本项目成功集成了 hCaptcha 人机验证,实现了:

  • ✅ 登录、注册、忘记密码三大页面的验证

  • ✅ 防止机器人攻击

  • ✅ 登录失败次数限制

  • ✅ 邮箱验证码机制

  • ✅ 完整的错误处理

项目现在具备了完善的验证码保护机制,可以有效防止恶意注册和暴力破解。


本文由萧兮的博客原创发布,欢迎转载,转载务必保留原文链接。

萧兮的博客https://www.20010515.xyz · 原文:https://www.20010515.xyz/posts/a6cf2841-cb92-4157-a86c-6bff63b784a2