human-verify
v1.1.1
Published
人机验证库 - 行为分析验证
Maintainers
Readme
HumanVerify 人机验证库
基于行为特征分析的人机验证库,前后端分离架构。Vue 已打包进库,无需使用者安装 Vue。
包内容
human-verify/
├── frontend/
│ ├── human-verify.es.js # 前端 ES 模块(混淆,Vue 已打包)
│ └── human-verify.umd.js # 前端 UMD 模块(混淆,Vue 已打包)
├── backend/
│ └── index.js # 后端验证库(混淆)
└── package.json安装
npm install human-verify前端使用
组件模式(Vue 3 项目)
<script setup>
import { HumanVerify } from 'human-verify'
async function onVerified(result) {
const details = result.details
const pow = details?.pow
if (pow) {
// 使用者自行调用 pow-verify 接口完成最终验证
const verifyResp = await fetch('/api/verify/pow-verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ sessionId: details.sessionId, nonce: pow.nonce })
})
const verifyResult = await verifyResp.json()
if (verifyResult.passed) {
console.log('最终验证通过')
}
}
}
</script>
<template>
<HumanVerify
challenge-url="/api/verify/challenge"
pow-challenge-url="/api/verify/pow-challenge"
@verified="onVerified"
@failed="onFailed"
/>
</template>函数模式
import { humanVerify } from 'human-verify'
const result = await humanVerify({
challengeUrl: '/api/verify/challenge',
powChallengeUrl: '/api/verify/pow-challenge',
onProgress: (progress, status) => {
console.log(`${progress}%: ${status}`)
}
})
if (result.passed && result.pow) {
// 使用者自行调用 pow-verify 接口完成最终验证
const verifyResp = await fetch('/api/verify/pow-verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
sessionId: result.sessionId,
nonce: result.pow.nonce
})
})
const verifyResult = await verifyResp.json()
console.log('最终验证结果:', verifyResult)
}自定义元素模式(纯 HTML)
<script src="/lib/human-verify.umd.js"></script>
<human-verify
challenge-url="/api/verify/challenge"
pow-challenge-url="/api/verify/pow-challenge"
onverify-id="my-callback"
></human-verify>
<script>
window.HumanVerifyCallbacks.set('my-callback', async (result) => {
const details = result.details
const pow = details?.pow
if (pow) {
// 使用者自行调用 pow-verify 接口
const verifyResp = await fetch('/api/verify/pow-verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ sessionId: details.sessionId, nonce: pow.nonce })
})
const verifyResult = await verifyResp.json()
if (verifyResult.passed) {
console.log('验证通过,得分:', details.score)
}
}
})
</script>组件属性
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| challenge-url | string | '/api/verify/challenge' | 获取挑战接口 URL |
| pow-challenge-url | string | '/api/verify/pow-challenge' | 提交行为验证 + POW 挑战接口 URL |
| timeout | number | 30000 | 超时时间(ms) |
| onverify-id | string | — | 回调 ID,通过 window.HumanVerifyCallbacks.set(id, fn) 注册 |
组件事件
| 事件 | detail | 说明 |
|------|--------|------|
| verified | { passed, reason, details } | 行为验证通过 + POW 计算完成,pow 等信息在 details 中 |
| failed | { reason, details } | 验证失败,详细信息在 details 中 |
| progress | { progress, status } | 进度更新 |
返回结果
interface VerifyResult {
passed: boolean // 行为验证是否通过
score: number // 行为评分 (0-100)
sessionId: string // 会话 ID(供使用者调用 pow-verify 接口)
pow?: {
challenge: string
nonce: number // POW 计算结果(供使用者提交)
requiredLeadingBits: number
}
reason: string // 提示信息:仅返回"人机验证成功"或"人机验证失败"
details?: {
serverReason?: string // 详细信息(如失败原因原文、服务器返回的原始原因)
}
}注意:
reason字段仅用于 UI 展示,始终返回固定文本。如需获取原始失败原因,请查看details.serverReason。
后端使用
import {
createSession,
verifySession,
generatePOWChallenge,
verifyPOWSolution,
detectAutomation,
analyzeBehavior
} from 'human-verify/backend'后端库为 ESM 格式,Node.js 18+。
函数列表
| 函数 | 参数 | 返回值 | 说明 |
|------|------|--------|------|
| createSession() | 无 | { sessionId, publicKey, challenge, expiresAt } | 创建会话,生成 RSA 密钥对 |
| verifySession(sessionId, encryptedData, threshold?) | sessionId, 加密数据, 分数阈值(默认 50) | { success, passed, score, reason, details } | 验证加密数据并评分,reason 统一返回"人机验证成功/失败",原始原因在 details.serverReason |
| generatePOWChallenge(sessionId) | sessionId | { success, challenge, difficulty, requiredLeadingBits } | 根据评分生成 POW 挑战 |
| verifyPOWSolution(sessionId, nonce) | sessionId, nonce | { success, passed, score? } | 验证 POW 结果,无论成功失败都销毁会话(防重放) |
| detectAutomation(fingerprint) | DeviceFingerprint | { isBot, reason } | 检测自动化工具 |
| analyzeBehavior(data, challengeResult) | 行为数据, 挑战结果 | { passed, score, reason, details } | 分析行为数据,reason 统一返回固定文本,details.serverReason 存原始原因 |
示例
import express from 'express'
import { createSession, verifySession, generatePOWChallenge, verifyPOWSolution } from 'human-verify/backend'
const app = express()
app.use(express.json())
// 1. 创建验证会话
app.post('/api/verify/challenge', (req, res) => {
const session = createSession()
res.json(session)
})
// 2. 行为验证 + POW 挑战
app.post('/api/verify/pow-challenge', (req, res) => {
const { sessionId, encryptedData, threshold } = req.body
const result = verifySession(sessionId, encryptedData, threshold)
if (!result.success) {
return res.status(400).json({ error: result.error })
}
if (!result.passed) {
// 验证失败,会话已销毁
return res.json({ passed: false, score: result.score, reason: result.reason, details: result.details })
}
// 验证通过,生成 POW 挑战(会话保留供 POW 验证)
const pow = generatePOWChallenge(sessionId)
res.json({ passed: true, score: result.score, pow, reason: result.reason })
})
// 3. POW 验证(使用者自行调用)
app.post('/api/verify/pow-verify', (req, res) => {
const { sessionId, nonce } = req.body
const result = verifyPOWSolution(sessionId, nonce)
if (!result.success) {
return res.status(400).json({ error: result.error })
}
// 无论成功失败,会话都已销毁(防重放)
res.json({ passed: result.passed, score: result.score })
})
app.listen(3000)验证流程
前端 后端
│ │
│ POST /api/verify/challenge │
│ ──────────────────────────────────────────► │ createSession()
│ ◄────────────────────────────────────────── │ → { sessionId, publicKey }
│ │
│ 采集指纹 + 行为数据 │
│ Web Worker 加密(RSA + AES) │
│ │
│ POST /api/verify/pow-challenge │
│ { sessionId, encryptedData } │
│ ──────────────────────────────────────────► │ verifySession() → 评分
│ │ (失败则销毁会话)
│ │ generatePOWChallenge()
│ ◄────────────────────────────────────────── │ → { passed, score, pow }
│ │
│ Web Worker 计算 POW(实时进度) │
│ → 得到 nonce │
│ │
│ 使用者自行调用 pow-verify │
│ POST /api/verify/pow-verify │
│ { sessionId, nonce } │
│ ──────────────────────────────────────────► │ verifyPOWSolution()
│ │ (销毁会话,防重放)
│ ◄────────────────────────────────────────── │ → { passed, score }安全机制
- 防重放 — 会话一次性使用,验证即销毁,过期时间 5 分钟
- 双层加密 — RSA-OAEP-SHA256(2048 位)+ AES-256-GCM,Web Worker 中执行
- 工作量证明 — SHA-256 前导零位,难度 1-10 秒,Web Worker 计算
- 自动化检测 — Playwright / Puppeteer / Selenium / Headless 检测
- 设备指纹 — 100+ 采集项(Canvas / WebGL / Audio / Fonts / WebRTC)
- 代码混淆 — 控制流扁平化 / 死代码注入 / 字符串数组化
License
MIT
