Arcveil
ADeveloper Hub行为验证开发文档
开发者文档

产品介绍

按真实接入路径组织内容:先理解 Arcveil 解决什么问题,再选择接入方式,最后完成前端触发和服务端二次校验。

ARCVEIL DEVELOPER HUB

前端完成验证,服务端决定放行

按真实接入链路查找 SDK、服务端二次校验、API、插件和排障说明。先跑通一次完整请求,再逐步加入风险策略与运营能力。

稳定 SDK/sdk/tac.js
服务端校验second-verify
插件支持WP / DZ / HYBBS
Base URLhttps://tac.ptab.cn

学习路径

由浅入深,按真实接入顺序查文档

当前文档:概览 1 / 11

产品介绍

Arcveil 是给登录、注册、发帖、评论、活动领取等关键动作使用的人机风险验证服务。它负责识别人机风险,最终是否放行业务动作仍由你的服务端决定。

一分钟理解 Arcveil

用户准备执行关键动作时,前端 SDK 根据配置触发验证;验证通过后只返回一次性 token;业务后端再拿 App Secret 调用二次校验接口,确认 token 有效后才允许登录、注册、发帖或领取权益。

1关键动作登录、注册、找回密码、评论、发帖、活动领取。
2前端验证按点击、提交前或风险自适应方式触发 SDK。
3服务端校验业务后端调用 second-verify,避免伪造前端成功。
4业务放行结合账号、频率、风险等级决定通过、升级或拦截。

它解决什么问题

针对撞库爆破、批量注册、短信轰炸、活动薅羊毛、垃圾评论和高频接口滥用,在业务关键按钮前加入可配置的人机验证。

它不替代什么

前端验证不是最终授权。业务是否登录、注册、下单或提交成功,仍然必须由你的服务端完成二次校验后决定。

它如何降低打扰

低风险请求可使用无感验证或 JS 预检;风险升高时再切换到滑块、旋转、点选、手势、文字点选等挑战。

核心能力

多验证方式无感、JS 预检、滑块拼图、旋转拼图、图标点选、手势连线、文字点选、算术验证。
强确认通道支持公众号扫码和 OneBot 机器人通道,适合高风险动作或站外确认。
降级链配置按风险、设备和场景配置验证顺序,避免所有用户都承受同一种挑战。
可观测分析调用日志、失败原因、风险来源和验证趋势可用于后续策略调优。
插件适配WordPress/子比、Discuz、HYBBS 可直接下载安装,少写代码完成接入。
安全运营中心独立风控后台用于查看态势、策略成长、采集实验和自动巡检。

适用场景

场景建议策略
登录 / 注册 / 找回密码无感或 JS 预检起步,高风险升级到滑块、旋转或图标点选。
领券 / 抽奖 / 秒杀活动窗口可提高强度,使用旋转、图标点选或文字点选减少脚本通过。
评论 / 发帖 / 私信老用户低风险无感,新账号、高频提交升级挑战并联动审核。
高风险确认需要用户身份或社群确认时,使用公众号扫码或 OneBot 机器人通道。
推荐阅读顺序:

先看产品介绍理解边界,再进入“创建应用并接入”,最后按照服务端二次校验文档完成业务闭环。

我是站长

优先去“插件接入说明”下载对应插件,通常只需要填写 App ID 和密钥,再按场景开启登录、注册、评论、发帖验证。

我是开发者

优先看“快速接入”和“前端 SDK”,选择提交前触发或风险自适应触发,再接入服务端二次校验。

我要排查问题

先看“错误码”和“调用日志”,确认域名白名单、App Secret、token 是否重复消费,以及 CDN 是否缓存了接口。

验证方式

平台支持多种人机验证方式,可以按业务风险、终端环境和用户体验要求组合成降级链。

低打扰

先判断是不是正常浏览器和正常用户,不打断大多数低风险请求。

无感 / JS 预检
通用挑战

适合登录、注册、找回密码等高频入口,用户学习成本最低。

滑块 / 旋转 / 算术
增强挑战

用于活动、防刷和异常设备,增加识别维度,减少固定脚本通过。

滑块 2.0 / 视差成像 / 图标 / 手势 / 文字
强确认

当业务需要站外身份确认时使用,让用户通过公众号或机器人完成确认。

公众号 / OneBot
自动选择

业务传 auto,由平台按应用配置、风险等级和降级链选择真实验证类型。

type: auto

低打扰验证

无感验证和 JS 预检适合低风险请求前置检测,尽量减少正常用户感知;风险升高时再进入手动挑战。

常规交互验证

滑块拼图、旋转拼图、算术验证适合登录注册、找回密码、普通表单提交等高频场景。

增强与强确认

手势连线、图标点选、文字点选适合活动防刷和异常流量;公众号扫码、OneBot 通道适合高风险动作确认。

类型中文名称类别适用场景使用建议
INVISIBLE无感验证低打扰低风险登录、普通浏览、老用户操作适合作为降级链第一层,异常时升级挑战。
JS_CHALLENGEJS 预检低打扰脚本探测、浏览器能力检查可在手动验证前先做轻量检测。
SLIDER滑块拼图通用挑战登录、注册、找回密码通用入口优先选择,注意服务端二次校验。
SLIDER_2滑块 2.0增强挑战活动入口、异常设备、需要更强轨迹识别的登录注册曲线路径、旋转块和干扰缺口增强防御,可作为普通滑块升级版。
PARALLAX视差成像增强挑战活动防刷、异常设备、需要多维交互证据的高风险动作拖动滑块改变观察视角,让立体碎片组成完整实物。使用 200 个实物素材,服务端随机出题并校验角度、时长与轨迹;需 SDK v126(运行时 1.5.34)和 WebGL。旧客户端按应用降级链处理,加载失败不会直接放行。
ROTATE旋转拼图通用挑战中风险登录、支付确认、活动入口可替代单一滑块,降低固定答案风险。
ICON_CLICK图标点选增强挑战移动端、活动领取、异常设备适合增强挑战,需保证图标不溢出和干扰项质量。
GESTURE手势连线增强挑战中高风险提交、批量请求拦截建议控制难度,避免正常用户难以完成。
WORD_IMAGE_CLICK文字点选增强挑战活动防刷、内容提交、高风险表单素材和字体质量要稳定,不建议作为唯一兜底。
ARITHMETIC算术验证兜底验证低风险兜底、服务降级安全强度较轻,不建议用于高安全入口。
WECHAT_QR公众号扫码强确认账号绑定、高风险操作、人工确认需要配置客户自有公众号与回调。
CHANNEL_CODEOneBot 机器人通道强确认站外强确认、社群用户、备用验证需要配置 OneBot 上报地址和 access_token。
自动选择:

SDK 和生成接口支持 type: "auto"。它不是新的验证码类型,不会写成 AUTO 日志;服务端会根据当前应用允许的验证方式、降级链和风险建议选择一个真实类型,并在返回的 data.type 中展示实际结果。

推荐降级链:

普通业务可从 INVISIBLE → JS_CHALLENGE → SLIDER → ROTATE → ICON_CLICK 起步;活动或高风险业务再加入 WORD_IMAGE_CLICK、WECHAT_QR 或 CHANNEL_CODE。

安全边界

行为验证只能证明用户完成了挑战,最终业务放行必须由服务端结合 token 校验、账号状态、风控策略共同决定。

前端可以做什么

  • 加载 SDK 并展示验证弹窗。
  • 采集用户交互轨迹并提交挑战答案。
  • 拿到一次性 captcha token 后交给业务后端。
  • 根据失败原因提示用户重试或切换验证方式。

前端不能决定什么

  • 不能只凭 onSuccess 放行。 前端回调可能被伪造。
  • 不能暴露 App Secret。 密钥必须留在业务服务端。
  • 不能跳过 second-verify。 业务后端必须校验 token。
  • 不能长期缓存验证接口。 否则会导致挑战、版本和状态异常。

一次性 token

验证成功返回的 token 通常只应消费一次,重复提交应视为异常或失败。

域名白名单

应用应配置允许域名,阻止未知站点拿你的 App ID 生成挑战。

版本透明

对审计敏感的客户可使用固定版本 SDK、哈希校验和 SDK 安全透明页。

快速接入

标准路径是前端完成行为验证,业务后端拿 token 做二次校验,通过后再执行登录、注册、下单等动作。

1
创建应用在控制台创建应用,配置允许域名,保存 App ID 和 App Secret。
2
加载 SDK页面引入稳定入口 /sdk/tac.js,不要把密钥写到浏览器。
3
获得 tokenSDK 完成挑战后返回一次性 captchaToken。
4
后端放行业务后端调用 second-verify,成功后再处理业务请求。
推荐:表单提交前触发
<script src="https://tac.ptab.cn/sdk/tac.js"></script>
<form id="loginForm" action="/api/login" method="post">
  <input name="account" autocomplete="username">
  <input name="password" type="password" autocomplete="current-password">
  <button type="submit">登录</button>
</form>

<script>
TacCaptcha.mount({
  appId: "your_app_id",
  apiBase: "https://tac.ptab.cn",
  type: "auto",
  trigger: "submit",
  form: "#loginForm",
  tokenField: "captchaToken"
});
</script>
不要只信前端回调。

前端 onSuccess 只代表用户完成了挑战,最终是否允许登录、注册、下单,必须以业务后端的 /api/v1/captcha/second-verify 结果为准。

点击触发

适合页面上有独立“安全验证”按钮或验证区域的场景。用户主动点验证,完成后页面拿到 token。

点击验证按钮›完成挑战›业务按钮可提交
TacCaptcha.mount({ trigger: "click", button: "#verifyBtn" })

提交前触发

适合登录、注册、评论、发帖等表单。SDK 拦截 submit,验证通过后自动写入隐藏 token 并继续提交。

用户提交表单›先弹验证›带 token 提交
TacCaptcha.mount({ trigger: "submit", form: "#loginForm" })

风险自适应触发

适合想减少正常用户打扰的业务。低风险可走无感,中高风险自动升级到滑块 2.0 或强验证。

评估风险›选择验证强度›通过后放行业务
TacCaptcha.mount({ trigger: "risk", assessRisk: fn })

前端 SDK

SDK 负责展示验证弹窗、采集交互轨迹、提交答案,并把成功 token 交给业务页面。

SDK 安全页

发布通道

普通业务使用稳定入口 /sdk/tac.js。安全审计、自托管或 SRI 场景使用固定版本 /sdk/tac-vXX.js。

当前最新固定版本:自动同步中

交互更新:滑块允许微调,滑到最右端结束本次尝试;文字和图标点选支持撤销、重选,选满后点击确认。验证失败、取消或过期均不能放行业务,仍须服务端二次校验。

支持的验证方式

SLIDER / ROTATE滑块拼图、旋转拼图,适合通用登录注册。
PARALLAX / GESTURE / ICON_CLICK视差成像、手势连线、图标点选,适合增强验证。
INVISIBLE / JS_CHALLENGE低风险请求前置检测,可配合降级链。
WECHAT_QR公众号扫码/口令验证,适合特殊业务场景。
CHANNEL_CODE OneBot 机器人OneBot 标准 HTTP 上报确认,适合站外强确认和备用验证。
参数类型说明
appIdstring控制台创建应用后获得,前端可见。
typestring验证方式,可由应用配置或初始化参数指定。
apiBasestring默认使用当前站点,也可以指定 https://tac.ptab.cn。
triggerstringclick、submit、risk。不传时默认点击触发。
buttonselector / Element点击触发或提交触发时绑定的按钮,例如 #loginBtn。
formselector / Element提交前触发时绑定的表单。验证通过后可自动写入隐藏 token。
tokenFieldstring自动注入表单的隐藏字段名,默认 captchaToken。
assessRiskfunction风险自适应模式下返回 { level, type },用于选择无感、滑块 2.0 或强验证。
onBeforeVerifyfunction验证前回调。返回 false 可以阻止本次验证。
onVerifiedfunctionmount 验证成功后的业务回调,参数包含 token、trigger、form、button。
submitWithTokenfunction自定义业务提交逻辑。适合 Ajax 登录,不走浏览器原生表单提交。
onSuccessfunction验证成功回调,返回 token。
onFailfunction验证失败回调,用于提示用户重试或切换方式。
onClosefunction用户关闭验证弹窗时触发。

无感与安全预检:只在需要操作时弹窗

标准网页 SDK v126(运行时 1.5.34)默认采用 displayMode: 'managed'。INVISIBLE、JS_CHALLENGE 与 AUTO 在后台生成和执行轻量检查;服务端要求补充交互时才显示验证窗口。无感不等于无条件放行。

参数 / 方法默认值说明
displayModemanaged后台检查不弹窗;设置 always 保留旧可见检测窗口与窗口内重试。
silentTimeout10000 毫秒后台等待上限,可设 3000 至 30000 毫秒。超时可重试,不自动放行,不替代服务端有效期。
onState可选回调接收 loading、checking、challenge、verified、retry、failed、cancelled;可用时附实际 type。用于业务按钮反馈。
retry()用户触发onFail 的 action 为 retry 时保留当前实例,等待 retryAfter 秒后调用,沿用原会话与重试预算。
close()主动取消页面离开或组件卸载时清理采集和计时器;取消不作为验证失败。

先校验表单,再将按钮设为“提交中”并调用 show()。正常短请求无需显示安全检查提示;等待较久时可在按钮下提示。onFail 的 reason 是失败说明,retryAfter 是再次尝试前需要等待的秒数。网络错误不能当成高风险,也不能直接放行。

onSuccess / verified 只表示取得验证凭证。仍须将 token 交给自己的业务后端进行二次验证,确认后再执行登录、注册或订单操作;业务提交应保持幂等。前端不得放置应用密钥。SDK 不会预生成凭证,也不会读取密码或输入字段内容。

自动加载入口使用新版;固定版本 v121 及更早文件保持不变。插件、自托管与 App WebView 需检查实际加载的 SDK 版本。专用注册证据 SDK 独立发布,本次标准 SDK 更新不等于所有专用接入已升级。

体验无感验证 · 体验安全预检

无感验证进度提示(标准 Web SDK v126)

调用 show() 后,无感和安全预检立即显示底部轻提示,不遮挡页面、不抢焦点;超过 3 秒更新等待文案。完成验证、取消或升级交互挑战时关闭提示。失败提示 6 秒后收起,不会自动重试或放行。

silentFeedback: 'auto' 为默认值:未提供 onState 时使用内置提示;提供回调时由接入方展示按钮或行内进度。设置 silentFeedback: true 可始终启用内置提示,false 则关闭。请勿配置空 onState 回调后又不展示状态。

成功回调仅代表取得验证凭证。业务服务端的二次校验、下载地址获取及实际下载等待,仍须由业务按钮显示处理中。固定旧版 URL、自托管 SDK 和打包 SDK 不会自动更新,应升级至 /sdk/tac-v126.js(有 SRI 时同步更新校验值),或使用官方稳定入口。注册专用 SDK 不在此版本变更范围。

服务端二次校验

业务后端使用 App Secret 校验 token 并绑定业务请求。同一应用、scene、业务 key、摘要和 token 可在原有效期内重试成功回执;不同业务不可复用。

Secret 鉴权示例(默认兼容策略)
// businessRequest 来自业务服务端持久化记录,不信任浏览器传来的摘要。
// scene 必须与取题一致;启用 serverHmac 后使用完整 v2 签名示例。
const res = await fetch("https://tac.ptab.cn/api/v1/captcha/second-verify", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-App-Id": process.env.TAC_APP_ID,
    "X-App-Secret": process.env.TAC_APP_SECRET
  },
  body: JSON.stringify({
    token: captchaToken,
    scene: businessRequest.scene,
    businessRequestId: businessRequest.id,
    businessDigest: businessRequest.digest
  })
});

const ret = await res.json();
if (!res.ok || ret.code !== 200) throw new Error("captcha failed");
// ret.data.replayed 为 true 时返回已有成功回执;业务本身仍需幂等提交。
cURL 调试
curl -X POST https://tac.ptab.cn/api/v1/captcha/second-verify \
  -H "Content-Type: application/json" \
  -H "X-App-Id: $TAC_APP_ID" \
  -H "X-App-Secret: $TAC_APP_SECRET" \
  --data "$TAC_SECOND_VERIFY_JSON"

环境变量 TAC_SECOND_VERIFY_JSON 包含 token、scene、businessRequestId 和 businessDigest。仅在可信服务端调试;不适用于已强制 serverHmac 的应用。

推荐做法:前端只保存 App ID,App Secret 只保存在业务后端或插件服务端配置中。
业务幂等与有限期重试:

businessRequestId 为 8..128 位 [A-Za-z0-9_.:-],businessDigest 为可信业务内容的 64 位 SHA-256 十六进制,两项成对提供。旧请求两项都不传仍可一次性消费,但不支持成功回执重试。新接入明确传入与取题一致的 scene。

网络重试保持同一业务 key、digest、token 和 scene;签名请求每次生成新 nonce。成功返回 code=200 和 data.replayed,重试不续期。详见业务回执合同和可信服务端 v2 完整示例。

本地项目接入

本地开发环境可以接入 Arcveil,但页面、浏览器和业务服务端都需要能访问公网 TAC 服务,并且应用要允许本地域名。

1
允许本地域名在应用域名白名单中加入 localhost、127.0.0.1 或你的测试域名。
2
确认外网连通浏览器必须能加载 https://tac.ptab.cn/sdk/tac.js 并访问验证码 API。
3
后端保存密钥App Secret 放在本地后端环境变量或配置文件中,不写入前端页面。
4
调用二次校验前端拿到 token 后传给本地后端,由本地后端请求 TAC 完成 second-verify。

可以正常接入的情况

  • 本地电脑能访问公网,浏览器能加载 TAC SDK。
  • 业务后端能访问 https://tac.ptab.cn。
  • 应用白名单已经包含本地访问域名。
  • 前端只传 captcha token,后端再做二次校验。

常见失败原因

  • 纯内网环境。 页面或后端无法访问公网 TAC 服务。
  • 白名单未配置。 当前 Origin 不在应用允许域名内。
  • 只做前端回调。 没有把 token 交给后端 second-verify。
  • 密钥放错位置。 App Secret 暴露在浏览器或请求头配置错误。
纯内网项目说明:

如果用户项目完全不能访问公网,在线 TAC 验证无法完成。需要让内网环境通过代理访问 TAC,或改成可访问公网的测试域名后再验证。

插件接入说明

站长类网站优先使用插件接入。下载插件后一般只需要填写 App ID 和 App Secret,接口地址默认使用 Arcveil 官方服务。

打开下载中心

WordPress / 子比主题

适合 WordPress 登录、注册、评论、搜索、发帖投稿等场景。插件后台提供场景开关、版本安全、更新日志和在线更新提示。

配置项App ID / 密钥
推荐场景登录、评论、搜索
更新方式插件页检测更新

Discuz

适合论坛登录、注册、发帖、回帖等入口。建议先在测试站开启提交前触发,再同步到正式站。

配置项App ID / 密钥
推荐场景登录、注册、发帖
接入方式下载中心安装

HYBBS

适合 HYBBS 登录、注册、找回密码、发帖、回帖等入口。插件内置固定官方接口地址,并支持在线更新检测和更新日志。

配置项App ID / 密钥
推荐场景登录、找回、发帖
更新方式在线检测版本
插件接入边界:

插件会帮你完成前端触发和服务端二次校验,但仍需要在控制台创建应用、配置域名白名单,并确保站点服务器能访问 https://tac.ptab.cn。

小程序 / App 接入

移动端接入包 v1.1.1 已补齐小程序、uni-app、App WebView、Android/iOS 桥接示例和服务端代理;密钥只放业务后端,客户端只拿一次性 token。

下载移动端接入包

微信小程序

使用接入包里的 miniprogram/components/tac-captcha 原生组件。组件请求你的 proxyBase,由业务后端代理保存 App Secret 并调用 Arcveil 接口。

uni-app

使用 uniapp/tac-captcha.vue。H5、小程序、App 端统一走业务服务端代理,验证成功后把 captchaToken 提交给业务接口。

App WebView

把 app-webview/tac-webview.html 部署到你的 HTTPS 域名,Android/iOS 通过桥接接收 token。旧桥接是集成参考,宿主负责来源与生命周期;新的 Android 接入推荐使用下方 独立 SDK。

安全边界:

App Secret 不能写入小程序、uni-app、原生 App、WebView HTML 或任何前端代码包。客户端只拿 App ID 和一次性 token;真正的签名、校验和业务放行必须放在业务服务端。

Mobile Kit 1.1.1 生产代理要求 Redis 和自己的 HTTPS 原点;公开二验端点默认关闭,旧用户升级前阅读包内迁移文档。CORS 与客户端静态签名不能替代宿主认证。

1
下载接入包下载 tac-mobile-kit-1.1.1.zip,按终端复制小程序组件、uni-app 组件、WebView 页面或原生桥接示例。
2
部署代理服务部署 server-proxy/server.js 到业务 HTTPS 域名,环境变量保存 TAC_APP_SECRET。
3
客户端调用代理客户端配置 proxyBase,调用 /tac/mobile/generate 和 /tac/mobile/verify。
4
业务二次校验业务接口收到 captchaToken 后调用 second-verify,通过后再执行登录、注册、下单等动作。
小程序组件示例
<tac-captcha
  proxy-base="https://你的业务域名.com"
  scene="login"
  type="auto"
  bind:success="onTacSuccess"
  bind:fail="onTacFail" />

Page({
  onTacSuccess(e) {
    wx.request({
      url: "https://你的业务域名.com/api/login",
      method: "POST",
      data: { captchaToken: e.detail.token }
    });
  }
});
旧 v1 / hmac 代理签名参考
const canonical = [
  method.toUpperCase(),
  path,
  JSON.stringify(body || ""),
  nonce,
  timestamp
].join("|");

const signature = crypto
  .createHmac("sha256", process.env.TAC_APP_SECRET)
  .update(canonical)
  .digest("base64url");

上述旧 canonical 保持兼容,仅配合 v1 或 hmac 版本头使用;新 v2 的 bodyHash 与 canonical不同。密钥仅放服务端代理。

平台接入方式推荐验证方式注意事项
微信小程序原生组件 + 服务端代理支持无感、JS 预检、滑块、滑块 2.0、旋转、图标点选、手势、文字点选、滑动还原、算术、公众号、OneBot把代理域名加入 request 合法域名。
uni-appVue 组件 + 服务端代理与小程序组件同一套类型字段,H5/小程序/App 统一代理不同端 UI 可按验证方式单独调优。
Android / iOS WebViewWebView 页面 + JS Bridge支持当前 Web SDK 验证方式桥接只传 token,不传密钥。
原生 App API客户端调用业务代理优先触屏友好验证,强确认作为备用最终仍以业务后端 second-verify 为准。

Android SDK

v1.0.0 接入候选版:安全 WebView 容器、Java/Kotlin 接口、签名资源与业务后端会话。支持目标为 Android 8.0+,需要具备安全消息能力的 Android System WebView。

下载 SDK 与示例
验证范围

已完成构建及 API35 模拟器合成链路测试。各验证方式的生产闭环、真实手机和厂商兼容仍待验收;此版本不代表所有安卓设备均已验证。完整说明见 Android 接入指南。

1
安装依赖解压 ZIP,将其中 maven/ 配成项目本地 Maven 仓库,添加 cn.tac:arcveil-android:1.0.0。该坐标尚未发布到 Maven Central。
2
业务后端签发会话按 宿主适配文档接入自己的认证、业务记录与事务;App Secret 只放后端,使用 Redis 共享状态。
3
App 展示验证解析后端返回的 session,调用 captcha.show();用户关闭、超时与失败都不能执行业务。
4
后端确认业务将 token、sessionToken、原业务 ID 发回宿主;后端绑定账号、场景、参数摘要,二验通过后幂等执行业务。
Kotlin
val captcha = ArcveilCaptcha(this)
val session = CaptchaSession.fromJson(sessionJson)
captcha.show(session) { result ->
    if (result.status == CaptchaResult.Status.VERIFIED) {
        // 异步提交自己的业务后端,二验通过后才放行
        submitToOwnBackend(session.sessionToken,
            result.token, businessRequestId)
    } else {
        showResult(result.code)
    }
}
Java
ArcveilCaptcha captcha = new ArcveilCaptcha(this);
CaptchaSession session = CaptchaSession.fromJson(sessionJson);
captcha.show(session, result -> {
    if (result.status == CaptchaResult.Status.VERIFIED) {
        submitToOwnBackend(session.sessionToken,
            result.token, businessRequestId);
    } else {
        showResult(result.code);
    }
});
行为约定
初始化 / 预加载FragmentActivity 宿主;preload() 只准备静态资源,不生成挑战。
取消 / 退出cancel() 取消当前会话,close() 释放实例;单会话终态只返回一次。
旋转 / 后台Activity 重建取消旧会话;后台恢复沿用原过期时间,不能持久化通过状态。
能力与权限会话提供桥接协议及宿主允许方式;默认 auto,云端在生成挑战时最终检查应用配置与权限。
外部渠道仅支持用户操作与宿主明确许可的 HTTPS 入口;公众号/OneBot 同设备跨 App 需单独验收。
发布 / 更新AAR 随 App 发版;Web 资源验证签名、hash、有效期和顺序号,支持稳定/灰度渠道,不下载 Dex。

完整安装、错误码与迁移文档 · 更新日志 · 隐私说明 · 测试范围 · 签名资源说明

验证码 API

普通网站接入优先使用 SDK 和 second-verify;下面接口用于服务端、插件和高级集成。

POST/api/v1/captcha/generateApp Header›
生成验证码挑战。前端 SDK 会自动调用;自研客户端可按应用配置生成指定类型挑战。
请求示例
curl -X POST https://tac.ptab.cn/api/v1/captcha/generate \
  -H "Content-Type: application/json" \
  -H "X-App-Id: your_app_id" \
  -d '{"type":"auto","scene":"login"}'

返回内容

返回 challenge ID、图片/任务数据、challengeToken、推荐验证类型和风控提示信息。

POST/api/v1/captcha/verifySDK 内部›
提交用户行为答案,验证成功后返回一次性 token。普通业务不要绕过 SDK 手写答案提交。

适用场景

SDK、插件或特殊客户端集成。public 模式必须带 generate 返回的 challengeToken;secret 模式需要签名。

成功结果

返回一次性 captcha token,业务后端还需要调用 second-verify 才能放行业务动作。

POST/api/v1/captcha/second-verify后端推荐›
业务后端使用 App Secret 校验前端 token。登录、注册、下单、发帖等业务动作应以这个结果为准。

请求头与业务字段

X-App-Id 和 X-App-Secret 必填;按应用启用 serverHmac 后还必须提供 HMAC。请求体携带一致的 scene,以及成对的 businessRequestId、businessDigest。

响应与回执

HTTP 成功且 JSON code=200 才表示通过;data.replayed=true 是同一业务的成功回执。其他结果不可放行,HTTP 200 也可能承载业务错误。查看完整合同。

POST/api/v1/app/create用户登录›
创建应用,返回 app_id 和 app_secret。普通用户建议直接在控制台应用管理中创建。

业务防护 API

用于把解决方案里的短信防轰炸、API 防刷、营销活动防刷、内容社区防灌水落到真实业务动作上。业务服务端调用该接口,根据决策执行放行、弹验证、限流或阻断。

去应用详情配置

配置入口

进入控制台应用详情,打开“场景防护”标签,按登录、注册、短信、API、营销活动、内容社区分别配置阈值和命中动作。

调用位置

在业务服务端发送短信、领券、投票、发帖、评论、开放 API 前调用,不建议只在前端判断。

返回决策

ALLOW 放行,CHALLENGE 要求先完成 TAC 验证,LIMIT 冷却限流,BLOCK 直接拦截。

POST/api/v1/guard/checkApp Secret›
业务服务端风控预判接口。它不是验证码答案校验接口,而是按场景策略给业务动作一个处理建议。
Node.js 示例
const resp = await fetch("https://tac.ptab.cn/api/v1/guard/check", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-App-Id": process.env.TAC_APP_ID,
    "X-App-Secret": process.env.TAC_APP_SECRET
  },
  body: JSON.stringify({
    scene: "sms",
    phone: "13800000000",
    path: "/api/sms/send",
    deviceId: req.headers["x-device-id"],
    riskScore: 0
  })
});

const guard = await resp.json();
const decision = guard.data && guard.data.decision;
if (decision === "ALLOW") {
  // 继续真实业务
} else if (decision === "CHALLENGE") {
  // 让用户完成 Arcveil 行为验证后再重新提交
} else if (decision === "LIMIT") {
  // 按 cooldownSeconds 提示稍后再试
} else {
  // BLOCK:拒绝本次请求
}

请求字段

scene 支持 login、register、sms、api、activity、content。可传 phone、userId、deviceId、path、riskScore、content 等辅助判断。

该接口需要 X-App-Id 和 X-App-Secret,只能由业务服务端调用。

决策HTTP / code业务处理建议
ALLOW200风险在阈值内,可以继续发送短信、提交内容或访问接口。
CHALLENGE202让前端弹出 Arcveil 行为验证,验证成功并二次校验后再继续业务。
LIMIT429进入冷却窗口,提示稍后再试,不继续消耗短信、权益或后端资源。
BLOCK403直接拒绝本次动作,并记录业务侧审计日志。
推荐闭环:

guard/check 负责业务动作前的风险决策;captcha/second-verify 负责用户完成验证码后的 token 校验。两个接口配合使用,才能同时兼顾风控和真实放行。

接口签名

新可信服务端接入使用 v2 HMAC,浏览器只配置 appId。v2 为服务端签名协议升级,不是 SDK v121 发布;v120 及旧固定 SDK 文件和版本信息保持不变。

Header说明
X-Tac-Nonce8..96 位 [A-Za-z0-9_-] 安全随机字符串;网络重试也要使用新 nonce。
X-Tac-Timestamp毫秒时间戳,服务端按 5 分钟窗口校验。
X-Tac-Signature使用 app_secret 对规范串做 HMAC-SHA256,输出 base64url。
X-Tac-Signature-Version新接入显式发送 v2。省略仅按旧 v1 兼容;v2、hmac 或未知版本不得失败后回退 legacy。
旧 v1 / hmac canonical(兼容参考)
const crypto = require("crypto");

function canonicalPayload(method, path, body, nonce, timestamp) {
  return [
    String(method || "POST").toUpperCase(),
    path,
    JSON.stringify(body || ""),
    nonce,
    timestamp
  ].join("|");
}

function sign(method, path, timestamp, nonce, body, secret) {
  return crypto
    .createHmac("sha256", secret)
    .update(canonicalPayload(method, path, body, nonce, timestamp))
    .digest("base64url");
}
新 v2 规范:

['tac-hmac-v2', appId, METHOD, path, bodyHash, nonce, timestamp].join('\n'),其中 bodyHash 为整个请求体稳定 JSON 的 SHA-256 小写十六进制。对象键递归排序、数组保序,签名结果为不带填充的 base64url。完整 canonical 规则及可运行服务端示例。

既有应用默认允许显式 legacy 和旧 v1 的 legacy 兼容至 2026-12-31T23:59:59.999Z(UTC);分别由 allowLegacy、allowV1Legacy 控制。应用可明确配置有限的 legacyUntil,完成迁移后关闭旧兼容,并按需启用 serverHmac。新 v2 与 hmac 校验失败绝不回退。

额度口径:按已完成验证尝试(completed-attempt)提交一次计费事件;取题、pending 和技术故障不计费,同一完成事件及二验回执重试不重复扣费。客户端超时不代表服务端未完成入账。查看计费与重试边界。

Webhook

Webhook 用于把验证结果、风险事件、异常调用推送到业务系统,适合审计、风控联动和告警。

配置入口

控制台选择应用后进入 Webhook 配置,填写回调 URL 和 Webhook Secret。平台推送时会携带签名,业务侧应校验后再入库。

进入 Webhook 配置

事件示例
{
  "event": "captcha.verified",
  "appId": "tac_xxxxx",
  "scene": "login",
  "captchaType": "SLIDER",
  "riskLevel": "low",
  "ip": "203.0.113.10",
  "createdAt": "2026-06-15T00:00:00.000Z"
}

上线安全检查

上线前至少完成密钥保护、域名限制、缓存策略、日志监控和异常回滚准备。

必须完成

  • App Secret 只保存在业务后端,不下发到浏览器或客户端。
  • 配置允许域名,阻止未知来源生成挑战。
  • 所有业务动作都以 second-verify 结果为准。
  • 验证码接口、SDK manifest、HTML 页面不做长期 CDN 缓存。
  • 保留调用日志、Webhook 推送和业务审计日志。

企业审计

有安全审计要求时,可使用固定版本 SDK、SHA256、SRI 和自托管方式。固定版本文件发布后不覆盖,便于审计留档。

查看 SDK 安全与透明度

可信存证

可信存证是旁路审计能力,用来证明日志批次在某个时间点形成过一致的哈希摘要,不影响实时验证码链路。

下载公开凭证

用户端能看到什么

用户控制台只展示最新区块高度、区块 Hash、批次 Root、Payload Hash、平台签名状态、锚定摘要,并提供公开验真凭证 JSON 下载。

完整区块浏览器、批次列表、锚定操作和运维复核入口保留在平台后台。

公开凭证包含什么

凭证包含区块 Hash、Prev Hash、批次 Root、Payload Hash、记录数量、平台公钥、签名、锚定摘要和复核结果。

凭证不包含原始调用日志、用户隐私数据、后台批次明细或平台私钥。

区块式哈希链

每个公开区块带有上一块 Hash、批次 Root 和 Payload Hash,便于发现后续篡改或缺块。

平台签名

平台使用 Ed25519 对区块 Hash 签名,凭证提供公钥指纹和公钥,便于外部复核。

可外部锚定

当前支持记录外部锚定摘要;是否接入独立节点、时间戳服务或第三方链,应按业务审计需求单独配置。

边界说明:当前不是第三方公链能力,不应对外表达成外部链背书或同等安全等级。它的价值是可复核、可留档、可扩展锚定。

错误码

业务侧应把错误码转成明确可操作的提示,避免只展示原始英文。

错误码含义建议处理
answer_invalid答案或行为轨迹不匹配。提示用户重新验证,不要直接切 JS 预检放行。
captcha_expired挑战已过期或 token 被重复消费。重新生成挑战,检查是否重复提交。
app_invalidApp ID 不存在、被禁用或域名不匹配。检查应用配置和域名白名单。
quota_exceeded套餐额度不足或已到期。提醒续费、购买套餐或增量包。
rate_limited请求频率过高。降低重试频率,检查是否存在脚本刷接口。
signature_invalid签名、时间戳或 nonce 不合法。检查签名规范串、服务器时间和密钥。

FAQ

常见接入问题集中在域名、缓存、密钥位置和二次校验流程。

本地项目能否验证?

可以,但需要本地页面能访问公网 TAC 服务,并在应用里配置允许的 localhost 或测试域名。纯内网且无法访问外网会失败。

CDN 缓存怎么配?

HTML、/sdk/tac.js、/sdk/manifest.json 和验证码 API 不建议长期缓存。图片素材可缓存,验证接口不能缓存。

为什么要二次校验?

前端环境不可信,token 必须由业务服务端拿 App Secret 校验,才能防止伪造成功回调。

线上如何排查异常?

先看控制台调用日志、应用配置、域名白名单、风控记录和 Webhook 推送,再结合业务侧请求 ID 排查。

没有匹配的文档内容,换个关键词试试。
已复制