npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

human-verify

v1.1.1

Published

人机验证库 - 行为分析验证

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