星辉数盾 文档 / 人机验证 BitCaptcha
星辉数盾 / 文档 / 人机验证

接入人机验证 BitCaptcha

对应 SDK 0.6.2 · 更新于 2026-09-15

人机验证 BitCaptcha 是星辉数盾的人机验证服务:前端拿一次性凭证,后端核销放行。四端一份 SDK,几分钟接上。

快速接入

三步接上一个登录 / 注册 / 下单的人机验证。

  1. 1控制台注册,拿到站点的 captcha_id(客户端用)与 secret_key(只放后端)。
  2. 2前端引入 SDK,用户通过后在 onVerify 拿到 validate,随业务请求提交。
  3. 3后端带 secret_key 调核销接口,result:true 才放行。
index.html
<div id="captcha"></div>
<script src="https://shudun.bitbeam.cn/sdk/bitcaptcha.min.js"></script>
<script>
  BitCaptcha.init({
    element: '#captcha',
    captchaId: 'YOUR_CAPTCHA_ID',
    onVerify(err, data) {
      // data.validate 交给后端核销
      if (!err) submitLogin({ captcha: data.validate })
    }
  })
</script>
前端"通过"不代表安全——必须在后端用 secret_key 核销 validate,通过才放行。见服务端二次校验

工作原理与凭证模型

三个角色:客户端(网页 / 小程序 / App)展示拼图并拿到一次性凭证 validate;你的业务后端secret_key 核销凭证;星辉数盾服务出题、判定、签发凭证。

名词放在哪说明
captcha_id客户端站点标识,24 位十六进制。泄露无害,配合 Origin 白名单可防盗用。
secret_key仅业务后端核销凭证用,48 位十六进制。可在控制台轮换,轮换后旧 key 立即失效。
validate客户端 → 业务后端一次性通过凭证(带签名与过期时间),约 120 字符。
tokenSDK 内部一道题的标识,2 分钟过期,只能校验一次,业务侧无需关心。

服务端二次校验

这一步必须做,而且只能在你的服务器上做。只有核销成功才放行业务。

curl -X POST https://shudun.bitbeam.cn/api/v1/captcha/verify \
  -H 'Content-Type: application/json' \
  -d '{"validate": "前端提交的 validate", "secret_key": "你的 secret_key"}'
返回字段类型说明
resultbooleantrue 放行;false 拒绝
captcha_idstring核销的站点 id,建议与你配置的比对
tokenstring本题标识,用于日志关联
reasonstringused 已核销 · expired 超 180s · bad_signature 被篡改或 secret 已轮换 · bad_secret secret 不对 · malformed 格式错误
每个 validate 只能核销一次,重放会得到 used;接口超时(建议 5s)按拒绝处理并提示重试。

安全与数据

  • 答案只在服务端;客户端拿到的是题图和运动方式。位置与角度必须同时对上,每题曲线不同。
  • 一道题只能校验一次,2 分钟过期;凭证只能核销一次,180 秒过期。
  • 服务端综合拖动轨迹、时序、运行环境等信号打分,并对同一来源的连续失败做冷却。
  • 智能无感知按风险分级:多数真人无感通过,可疑流量自动升级为图形验证而非直接拒绝,兼顾安全与转化。可疑来源会被转入"严格"一段时间(一律图形验证);站点也可在控制台直接设为严格模式——登录、注册、领券这类高价值动作建议选它。
  • 校验请求的载荷在客户端加密传输,配合 SDK 版本轮换抬高脚本伪造成本。
  • Origin 白名单可防止其他网站盗用你的 captcha_id 消耗额度。
  • 只加载图片不验证的刷图流量会被自动识别并临时限制,不消耗你的额度;控制台会提示,误判可联系我们解除。
必须 https。Web 端加密依赖浏览器安全上下文,http 下(localhost 除外)会退化为明文并被服务端拒绝。

采集了什么

为区分人和机器,SDK 在拖动时上报:滑块位移与轨迹(相对坐标与时间)、屏幕尺寸与像素比、语言与时区、是否触屏、是否处于自动化环境。服务端记录请求 IP 与 UA 摘要用于绑定与限流,保留不超过 10 分钟。不采集 Cookie、账号、页面内容或输入框内容。以上口径可直接写入隐私政策。

额度与账单

验证次数计费:用户提交答案一次、或智能无感知直接通过一次,各算一次;验证码加载与换题不计。额度属于账号,名下所有站点共用。

  • 每月 10,000 次免费额度,按 UTC 自然月、每月 1 日重置;控制台「概览」有本月用量与进度,「用量」页可查按月账单。
  • 免费额度用完后自动从次数包扣,按到期先后扣;次数包在控制台「充值」页购买(支付宝),12 个月有效,支付成功立即到账、不影响已有余额。
  • 免费额度用完且没有余额时,取题接口返回 429(detail: quota_exceeded),验证码显示"加载失败",充值或下月重置后自动恢复;控制台会提前提示。
  • 企业客户、发票、对公转账或不限量方案请联系我们,后台入账即时生效。
超额只影响取题,已发出去的题仍可正常完成校验与核销,不会把正在验证的用户卡在半路。

私有化部署

shell
git clone ... shudun && cd shudun
# 改 docker-compose.yml 里的 SESSION_SECRET / PUBLIC_URL
docker compose up -d --build
curl -s http://127.0.0.1:8790/api/v1/health   # {"status":"ok"}
环境变量默认说明
BITCAPTCHA_PUBLIC_URL按请求推断对外地址:控制台 / 文档 / 产品页里的接入代码与 llms.txt 里的域名都从这里来
BITCAPTCHA_SESSION_SECRET随机控制台登录态签名(固定一个值;登录态闲置 30 天失效,活跃自动续期),生产必填,否则重启即登出
BITCAPTCHA_SDK_KEYbitcaptcha-sdk-v1与三端 SDK 内置值一致,改动需同时发新版 SDK
BITCAPTCHA_DATABASE_URL必填PostgreSQL 连接串;compose 自带一个,也可指向云数据库
BITCAPTCHA_REDIS_URL空(进程内)多实例 / 多 worker 必填
BITCAPTCHA_TRUST_PROXY0nginx 之后置 1,否则限流按代理 IP 算
BITCAPTCHA_ALLOW_REGISTER1私有部署建好账号后可关闭注册
BITBEAM_ADMIN_EMAILS超级管理员邮箱名单(逗号分隔),可进 /admin 平台后台
BITBEAM_LLM_KEY文档「问 AI」的模型服务密钥(环境变量只作缺省;后台「平台配置」可改,开关默认关闭)
BITBEAM_FREE_QUOTA10000每账号每月验证次数默认额度,0 为不限;后台可按账号覆盖
BITBEAM_ALERT_WEBHOOK告警群机器人地址(飞书 / 钉钉 / 企业微信自动识别);后台「平台配置」可改,以后台为准
BITBEAM_METRICS_TOKEN开启 /api/v1/metrics(Prometheus 格式)的访问 token,空则关闭
BITBEAM_ALIPAY_APP_ID / PRIVATE_KEY / PUBLIC_KEY支付宝电脑网站支付:应用 ID、应用私钥、支付宝公钥;三者齐了控制台才开放自助购买
BITBEAM_ALIPAY_GATEWAY正式网关联调时换成沙箱网关
BITBEAM_PACKSJSON 数组整体替换次数包目录(名称 / 次数 / 价格 / 有效期)
BITBEAM_SIGNUP_CREDITS0注册赠送的一次性次数(12 个月有效);想改成"一共送 1 万"就设它并把 FREE_QUOTA 置 0
BITCAPTCHA_TOLERANCE / RISK_THRESHOLD5 / 0.6拼图容差(px)/ 行为风险阈值

完整变量见 server/.env.example

探活与监控

GET /api/v1/health 会实际检查数据库与 Redis,任一异常返回 503,可直接接云监控或 UptimeRobot 探活;进程内每分钟也自检一次,依赖故障与恢复、未捕获异常、错误激增、商户额度到 80% / 100% 都会推到告警群。配置 BITBEAM_METRICS_TOKEN 后,GET /api/v1/metrics(Authorization: Bearer <token>)输出 Prometheus 指标:请求量与时延、取题 / 校验 / 通过、拦截与冷却、数据库连接池。

Web / H5 SDK

无依赖,一个 <script> 引入,兼容现代浏览器与移动端 WebView(需 https,localhost 除外)。样式由 SDK 自动加载。

四种类型:sense 智能无感知(点一下即过,可疑流量自动升级为图形验证)、slider 增强版滑动拼图(默认)、textclick 文字点选(enhanced:true 文字带旋转更防破解)、iconclick 图标点选。无论哪种,通过后都拿到一次性 validate,业务后端二次核销才算数。宽度默认自适应铺满容器并在 minWidth–maxWidth(280–400)间收敛;要固定宽传数字 width:320

初始化参数

参数类型默认说明
elementstring | Element必填容器选择器或元素
captchaIdstring必填控制台里的 captcha_id
typestring'slider'sense 智能无感知 / slider 滑动拼图 / textclick 文字点选 / iconclick 图标点选
enhancedbooleantrue仅文字点选:true 旋转 / false 正放
modestring'embed'embed 嵌入 / popup 弹出 / float 触发
widthnumber | string'100%'默认自适应;传数字则固定 px
theme / langstringlight / auto主题与语言,见多语言与主题
maxErrorsnumber5连续失败几次后停止自动换题,改为点击刷新
lazybooleantrue嵌入 / 触发式滚进视口附近才取题;首屏之外的验证码不提前加载。三端同名
onReady / onVerify / onError / onClosefunction-就绪 / 校验结果 / 错误 / 弹窗关闭

回调 onVerify(err, data)

字段说明
err通过为 null;失败时 err.code 为错误码,SDK 会 1s 后自动换题。连续失败达到 maxErrors 改为"点击刷新";若某次失败触发了来源冷却,err.retryAfter 给出秒数,控件直接进入倒计时、到点自动重新取题
data.validate一次性通过凭证,提交给后端核销
data.token / data.captchaId本题标识 / 站点 id

实例方法

refresh()换一题
popUp() / close()弹出式:手动打开 / 关闭
getValidate()取最近一次通过的 validate
reset()清掉通过状态并换题(业务提交失败后重新验证)
destroy()移除组件与事件

微信小程序

下载组件包,解压后把 bitcaptcha 目录放到小程序 components/ 下;后台"开发设置 → request 合法域名"加入接口域名。拖动在视图层(WXS)处理,跟手不卡顿。

page.wxml / page.js
<!-- page.json -->
{ "usingComponents": { "bitcaptcha": "/components/bitcaptcha/index" } }

<!-- page.wxml -->
<bitcaptcha captcha-id="YOUR_CAPTCHA_ID" api-base="https://shudun.bitbeam.cn"
             mode="embed" bind:verify="onVerify" />
<!-- 智能无感知:点一下,安全用户直接过,可疑自动切成拼图 -->
<bitcaptcha captcha-id="YOUR_CAPTCHA_ID" api-base="https://shudun.bitbeam.cn"
             type="sense" bind:verify="onVerify" />

// page.js
Page({ onVerify(e) { const { validate } = e.detail
  wx.request({ url: '/login', method: 'POST', data: { captcha: validate } }) } })
属性默认说明
captcha-id / api-base必填站点 id / 接口地址(https)
type / enhancedslider / true同 Web,enhanced="{{false}}" 为普通版
modeembedembed / popup(小程序无 hover,不提供 float)
width'100%'自适应;width="{{320}}" 固定 px
lazytrue滚进视口附近才取题 / 准备无感知;lazy="{{false}}" 立刻
bind:verify / bind:error-e.detail = { validate, token, captchaId } / { code }

Flutter

包已发布到 pub.dev,支持 iOS / Android / Web / 桌面。

pubspec.yaml
dependencies:
  bitcaptcha_flutter: ^0.6.2
dart
import 'package:bitcaptcha_flutter/bitcaptcha_flutter.dart';

// 嵌入式
BitCaptcha(
  captchaId: 'YOUR_CAPTCHA_ID', apiBase: 'https://shudun.bitbeam.cn',
  onVerify: (r) => login(captcha: r.validate),
)

// 弹窗式:用户关闭返回 null
final r = await showBitCaptcha(context,
    captchaId: 'YOUR_CAPTCHA_ID', apiBase: 'https://shudun.bitbeam.cn');
if (r != null) login(captcha: r.validate);

// 文字点选:BitCaptchaText / showBitCaptchaText(enhanced: bool)
// 智能无感知:点一下,安全用户直接过,可疑自动弹出拼图
BitCaptchaSense(
  captchaId: 'YOUR_CAPTCHA_ID', apiBase: 'https://shudun.bitbeam.cn',
  onVerify: (r) => login(captcha: r.validate),
)
参数默认说明
captchaId / apiBase必填站点 id / 接口地址
onVerify必填r.validate r.token r.captchaId
fluid / widthtrue / 320默认铺满父容器;fluid:false 用固定 width
theme / lang / maxErrorslight / auto / 5同 Web,const BitCaptchaTheme.dark() 或自定义色
lazytrue滚进视口附近才取题 / 准备无感知(三端同名);不在滚动容器里立即生效

错误码

客户端 onVerifyerr.code(小程序 bind:errordetail.code)。都由 SDK 自动处理,列出便于埋点。

code含义SDK 行为
mismatch没拼到位提示"验证失败",1s 后换题
behavior轨迹或环境判定为机器提示"操作异常",1s 后换题
token_expired题目超 2 分钟或已校验过提示过期,换题
token_mismatch取题与校验不是同一客户端换题
bad_payload载荷无法解密(SDK 与服务端版本不一致)换题;持续出现请升级 SDK

加载失败的分类

取题 / 无感知请求失败时走 onError(小程序 bind:error,Flutter onError 收到 BitCaptchaException),错误对象带 code;三端把原因分开告诉用户,不会一句"加载失败"让用户以为你的站点坏了。

code含义用户看到
rate_limited / cooldown请求过于频繁,或短时间内失败过多进入冷却;响应带 Retry-After(秒),错误对象里是 retryAfter"操作太频繁,N 秒后自动重试",倒计时期间点击无效,到点自动重新取题
network请求没到服务端(断网 / 超时 / 图片没下下来)"网络不给力,点击重试"
server服务端 5xx"服务开小差了,点击重试"
quota_exceeded账号本月额度用完且没有余额"加载失败,点击重试"(额度是商户侧的事,不向终端用户解释;控制台会提前提示)
http其它 4xx:400 未知 captcha_id · 403 来源不在 Origin 白名单 / 账号已停用"加载失败,点击重试";接入时看 err.status / err.detail 排查

多语言与主题

内置 zh-CN zh-TW en ja ko,lang:'auto' 按浏览器 / 系统语言归并。三端键名一致,可用 i18n 逐条覆盖。

js
BitCaptcha.init({ ..., lang: 'en',
  i18n: { slide: 'Drag to verify', success: 'Welcome back' } })

主题

Web 端除 theme:'dark' 外,可在容器上覆盖 CSS 变量;Flutter 用 BitCaptchaTheme(primary: ..., success: ...)

css
#captcha .bc { --bc-primary: #7c3aed; --bc-primary-soft: #ede9fe; }

AI 接入(MCP 与 llms.txt)

星辉数盾面向 AI 编程助手与 Agent 提供两种接入方式,让"接入人机验证"这件事对 AI 也友好。

llms.txt

遵循 llms.txt 约定,站点根目录提供两份纯文本文档:

/llms.txt精简索引,含核心模型与各页链接
/llms-full.txt全文 Markdown,可整份喂给 LLM

页面右上角"复制页面"可一键复制为 Markdown,或"在 ChatGPT / Claude 打开"直接带上文档提问。

MCP server

一个只读的 MCP 服务,暴露工具给 Claude Desktop、Cursor 等 AI 客户端调用,让它们在帮你写接入代码时能查文档、取片段、看服务状态。

工具作用
search_docs(query)在文档里检索,返回相关章节
get_snippet(platform, type)返回某端(web/mp/flutter/server)的接入代码
service_health()查询服务健康
claude_desktop_config.json
{
  "mcpServers": {
    "shudun": {
      "command": "python",
      "args": ["integrations/mcp-server/server.py"],
      "env": { "BITBEAM_HOST": "https://shudun.bitbeam.cn" }
    }
  }
}
MCP server 代码见仓库 integrations/mcp-server/;依赖 pip install mcp httpx。Cursor 等客户端配置方式类似。