它解决什么问题
针对撞库爆破、批量注册、短信轰炸、活动薅羊毛、垃圾评论和高频接口滥用,在业务关键按钮前加入可配置的人机验证。
按真实接入路径组织内容:先理解 TAC 解决什么问题,再选择接入方式,最后完成前端触发和服务端二次校验。
由浅入深,按真实接入顺序查文档
按任务快速进入详细文档,适合已经知道要查什么的开发者。
上线后排查问题、查看风险事件、配置安全策略时从这里进入。
TAC 是给登录、注册、发帖、评论、活动领取等关键动作使用的人机风险验证服务。它负责识别人机风险,最终是否放行业务动作仍由你的服务端决定。
用户准备执行关键动作时,前端 SDK 根据配置触发验证;验证通过后只返回一次性 token;业务后端再拿 App Secret 调用二次校验接口,确认 token 有效后才允许登录、注册、发帖或领取权益。
针对撞库爆破、批量注册、短信轰炸、活动薅羊毛、垃圾评论和高频接口滥用,在业务关键按钮前加入可配置的人机验证。
前端验证不是最终授权。业务是否登录、注册、下单或提交成功,仍然必须由你的服务端完成二次校验后决定。
低风险请求可使用无感验证或 JS 预检;风险升高时再切换到滑块、旋转、点选、手势、文字点选等挑战。
| 场景 | 建议策略 |
|---|---|
| 登录 / 注册 / 找回密码 | 无感或 JS 预检起步,高风险升级到滑块、旋转或图标点选。 |
| 领券 / 抽奖 / 秒杀 | 活动窗口可提高强度,使用旋转、图标点选或文字点选减少脚本通过。 |
| 评论 / 发帖 / 私信 | 老用户低风险无感,新账号、高频提交升级挑战并联动审核。 |
| 高风险确认 | 需要用户身份或社群确认时,使用公众号扫码或 OneBot 机器人通道。 |
先看产品介绍理解边界,再进入“创建应用并接入”,最后按照服务端二次校验文档完成业务闭环。
优先去“插件接入说明”下载对应插件,通常只需要填写 App ID 和密钥,再按场景开启登录、注册、评论、发帖验证。
优先看“快速接入”和“前端 SDK”,选择提交前触发或风险自适应触发,再接入服务端二次校验。
先看“错误码”和“调用日志”,确认域名白名单、App Secret、token 是否重复消费,以及 CDN 是否缓存了接口。
平台支持多种人机验证方式,可以按业务风险、终端环境和用户体验要求组合成降级链。
先判断是不是正常浏览器和正常用户,不打断大多数低风险请求。
无感 / JS 预检适合登录、注册、找回密码等高频入口,用户学习成本最低。
滑块 / 旋转 / 算术用于活动、防刷和异常设备,增加识别维度,减少固定脚本通过。
滑块 2.0 / 图标 / 手势 / 文字当业务需要站外身份确认时使用,让用户通过公众号或机器人完成确认。
公众号 / OneBot业务传 auto,由平台按应用配置、风险等级和降级链选择真实验证类型。
type: auto无感验证和 JS 预检适合低风险请求前置检测,尽量减少正常用户感知;风险升高时再进入手动挑战。
滑块拼图、旋转拼图、算术验证适合登录注册、找回密码、普通表单提交等高频场景。
手势连线、图标点选、文字点选适合活动防刷和异常流量;公众号扫码、OneBot 通道适合高风险动作确认。
| 类型 | 中文名称 | 类别 | 适用场景 | 使用建议 |
|---|---|---|---|---|
INVISIBLE | 无感验证 | 低打扰 | 低风险登录、普通浏览、老用户操作 | 适合作为降级链第一层,异常时升级挑战。 |
JS_CHALLENGE | JS 预检 | 低打扰 | 脚本探测、浏览器能力检查 | 可在手动验证前先做轻量检测。 |
SLIDER | 滑块拼图 | 通用挑战 | 登录、注册、找回密码 | 通用入口优先选择,注意服务端二次校验。 |
SLIDER_2 | 滑块 2.0 | 增强挑战 | 活动入口、异常设备、需要更强轨迹识别的登录注册 | 曲线路径、旋转块和干扰缺口增强防御,可作为普通滑块升级版。 |
ROTATE | 旋转拼图 | 通用挑战 | 中风险登录、支付确认、活动入口 | 可替代单一滑块,降低固定答案风险。 |
ICON_CLICK | 图标点选 | 增强挑战 | 移动端、活动领取、异常设备 | 适合增强挑战,需保证图标不溢出和干扰项质量。 |
GESTURE | 手势连线 | 增强挑战 | 中高风险提交、批量请求拦截 | 建议控制难度,避免正常用户难以完成。 |
WORD_IMAGE_CLICK | 文字点选 | 增强挑战 | 活动防刷、内容提交、高风险表单 | 素材和字体质量要稳定,不建议作为唯一兜底。 |
ARITHMETIC | 算术验证 | 兜底验证 | 低风险兜底、服务降级 | 安全强度较轻,不建议用于高安全入口。 |
WECHAT_QR | 公众号扫码 | 强确认 | 账号绑定、高风险操作、人工确认 | 需要配置客户自有公众号与回调。 |
CHANNEL_CODE | OneBot 机器人通道 | 强确认 | 站外强确认、社群用户、备用验证 | 需要配置 OneBot 上报地址和 access_token。 |
SDK 和生成接口支持 type: "auto"。它不是新的验证码类型,不会写成 AUTO 日志;服务端会根据当前应用允许的验证方式、降级链和风险建议选择一个真实类型,并在返回的 data.type 中展示实际结果。
普通业务可从 INVISIBLE → JS_CHALLENGE → SLIDER → ROTATE → ICON_CLICK 起步;活动或高风险业务再加入 WORD_IMAGE_CLICK、WECHAT_QR 或 CHANNEL_CODE。
行为验证只能证明用户完成了挑战,最终业务放行必须由服务端结合 token 校验、账号状态、风控策略共同决定。
不能只凭 onSuccess 放行。 前端回调可能被伪造。不能暴露 App Secret。 密钥必须留在业务服务端。不能跳过 second-verify。 业务后端必须校验 token。不能长期缓存验证接口。 否则会导致挑战、版本和状态异常。验证成功返回的 token 通常只应消费一次,重复提交应视为异常或失败。
应用应配置允许域名,阻止未知站点拿你的 App ID 生成挑战。
对审计敏感的客户可使用固定版本 SDK、哈希校验和 SDK 安全透明页。
标准路径是前端完成行为验证,业务后端拿 token 做二次校验,通过后再执行登录、注册、下单等动作。
/sdk/tac.js,不要把密钥写到浏览器。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 并继续提交。
TacCaptcha.mount({ trigger: "submit", form: "#loginForm" })
适合想减少正常用户打扰的业务。低风险可走无感,中高风险自动升级到滑块 2.0 或强验证。
TacCaptcha.mount({ trigger: "risk", assessRisk: fn })
SDK 负责展示验证弹窗、采集交互轨迹、提交答案,并把成功 token 交给业务页面。
普通业务使用稳定入口 /sdk/tac.js。安全审计、自托管或 SRI 场景使用固定版本 /sdk/tac-vXX.js。
当前最新固定版本:自动同步中
| 参数 | 类型 | 说明 |
|---|---|---|
appId | string | 控制台创建应用后获得,前端可见。 |
type | string | 验证方式,可由应用配置或初始化参数指定。 |
apiBase | string | 默认使用当前站点,也可以指定 https://tac.ptab.cn。 |
trigger | string | click、submit、risk。不传时默认点击触发。 |
button | selector / Element | 点击触发或提交触发时绑定的按钮,例如 #loginBtn。 |
form | selector / Element | 提交前触发时绑定的表单。验证通过后可自动写入隐藏 token。 |
tokenField | string | 自动注入表单的隐藏字段名,默认 captchaToken。 |
assessRisk | function | 风险自适应模式下返回 { level, type },用于选择无感、滑块 2.0 或强验证。 |
onBeforeVerify | function | 验证前回调。返回 false 可以阻止本次验证。 |
onVerified | function | mount 验证成功后的业务回调,参数包含 token、trigger、form、button。 |
submitWithToken | function | 自定义业务提交逻辑。适合 Ajax 登录,不走浏览器原生表单提交。 |
onSuccess | function | 验证成功回调,返回 token。 |
onFail | function | 验证失败回调,用于提示用户重试或切换方式。 |
onClose | function | 用户关闭验证弹窗时触发。 |
业务后端收到前端 token 后,调用 TAC 二次校验接口。token 一次性使用,验证成功后立即失效。
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: "login"
})
});
const ret = await res.json();
if (ret.code !== 200) throw new Error("captcha failed");
curl -X POST https://tac.ptab.cn/api/v1/captcha/second-verify \
-H "Content-Type: application/json" \
-H "X-App-Id: your_app_id" \
-H "X-App-Secret: your_app_secret" \
-d '{"token":"captcha_token","scene":"login"}'
本地开发环境可以接入 TAC,但页面、浏览器和业务服务端都需要能访问公网 TAC 服务,并且应用要允许本地域名。
localhost、127.0.0.1 或你的测试域名。https://tac.ptab.cn/sdk/tac.js 并访问验证码 API。https://tac.ptab.cn。纯内网环境。 页面或后端无法访问公网 TAC 服务。白名单未配置。 当前 Origin 不在应用允许域名内。只做前端回调。 没有把 token 交给后端 second-verify。密钥放错位置。 App Secret 暴露在浏览器或请求头配置错误。如果用户项目完全不能访问公网,在线 TAC 验证无法完成。需要让内网环境通过代理访问 TAC,或改成可访问公网的测试域名后再验证。
站长类网站优先使用插件接入。下载插件后一般只需要填写 App ID 和 App Secret,接口地址默认使用 TAC 官方服务。
适合 WordPress 登录、注册、评论、搜索、发帖投稿等场景。插件后台提供场景开关、版本安全、更新日志和在线更新提示。
适合论坛登录、注册、发帖、回帖等入口。建议先在测试站开启提交前触发,再同步到正式站。
适合 HYBBS 登录、注册、找回密码、发帖、回帖等入口。插件内置固定官方接口地址,并支持在线更新检测和更新日志。
插件会帮你完成前端触发和服务端二次校验,但仍需要在控制台创建应用、配置域名白名单,并确保站点服务器能访问 https://tac.ptab.cn。
移动端接入包 v1.1.0 已补齐小程序、uni-app、App WebView、Android/iOS 桥接示例和服务端代理;密钥只放业务后端,客户端只拿一次性 token。
使用接入包里的 miniprogram/components/tac-captcha 原生组件。组件请求你的 proxyBase,由业务后端代理保存 App Secret 并调用 TAC 接口。
使用 uniapp/tac-captcha.vue。H5、小程序、App 端统一走业务服务端代理,验证成功后把 captchaToken 提交给业务接口。
把 app-webview/tac-webview.html 部署到你的 HTTPS 域名,Android/iOS 通过桥接接收 token;原生示例见 app-native/android 和 app-native/ios。
App Secret 不能写入小程序、uni-app、原生 App、WebView HTML 或任何前端代码包。客户端只拿 App ID 和一次性 token;真正的签名、校验和业务放行必须放在业务服务端。
tac-mobile-kit-1.1.0.zip,按终端复制小程序组件、uni-app 组件、WebView 页面或原生桥接示例。server-proxy/server.js 到业务 HTTPS 域名,环境变量保存 TAC_APP_SECRET。proxyBase,调用 /tac/mobile/generate 和 /tac/mobile/verify。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 }
});
}
});
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");
| 平台 | 接入方式 | 推荐验证方式 | 注意事项 |
|---|---|---|---|
| 微信小程序 | 原生组件 + 服务端代理 | 支持无感、JS 预检、滑块、滑块 2.0、旋转、图标点选、手势、文字点选、滑动还原、算术、公众号、OneBot | 把代理域名加入 request 合法域名。 |
| uni-app | Vue 组件 + 服务端代理 | 与小程序组件同一套类型字段,H5/小程序/App 统一代理 | 不同端 UI 可按验证方式单独调优。 |
| Android / iOS WebView | WebView 页面 + JS Bridge | 支持当前 Web SDK 验证方式 | 桥接只传 token,不传密钥。 |
| 原生 App API | 客户端调用业务代理 | 优先触屏友好验证,强确认作为备用 | 最终仍以业务后端 second-verify 为准。 |
普通网站接入优先使用 SDK 和 second-verify;下面接口用于服务端、插件和高级集成。
/api/v1/captcha/generateApp Header›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、推荐验证类型和风控提示信息。
/api/v1/captcha/verifySDK 内部›SDK、插件或特殊客户端集成。public 模式必须带 generate 返回的 challengeToken;secret 模式需要签名。
返回一次性 captcha token,业务后端还需要调用 second-verify 才能放行业务动作。
/api/v1/captcha/second-verify后端推荐›X-App-Id 和 X-App-Secret 必填。高安全业务可叠加签名头。
code=200 表示通过;其他结果应阻断或进入人工/降级流程。
/api/v1/app/create用户登录›用于把解决方案里的短信防轰炸、API 防刷、营销活动防刷、内容社区防灌水落到真实业务动作上。业务服务端调用该接口,根据决策执行放行、弹验证、限流或阻断。
进入控制台应用详情,打开“场景防护”标签,按登录、注册、短信、API、营销活动、内容社区分别配置阈值和命中动作。
在业务服务端发送短信、领券、投票、发帖、评论、开放 API 前调用,不建议只在前端判断。
ALLOW 放行,CHALLENGE 要求先完成 TAC 验证,LIMIT 冷却限流,BLOCK 直接拦截。
/api/v1/guard/checkApp Secret›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") {
// 让用户完成 TAC 行为验证后再重新提交
} 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 | 业务处理建议 |
|---|---|---|
ALLOW | 200 | 风险在阈值内,可以继续发送短信、提交内容或访问接口。 |
CHALLENGE | 202 | 让前端弹出 TAC 行为验证,验证成功并二次校验后再继续业务。 |
LIMIT | 429 | 进入冷却窗口,提示稍后再试,不继续消耗短信、权益或后端资源。 |
BLOCK | 403 | 直接拒绝本次动作,并记录业务侧审计日志。 |
guard/check 负责业务动作前的风险决策;captcha/second-verify 负责用户完成验证码后的 token 校验。两个接口配合使用,才能同时兼顾风控和真实放行。
如果业务后端直接调用需要签名的接口,按下面规范生成签名。普通 SDK 接入通常只需要 second-verify。
| Header | 说明 |
|---|---|
X-Tac-Nonce | 8 到 96 位随机字符串,每次请求唯一。 |
X-Tac-Timestamp | 毫秒时间戳,服务端按 5 分钟窗口校验。 |
X-Tac-Signature | 使用 app_secret 对规范串做 HMAC-SHA256,输出 base64url。 |
X-Tac-Signature-Version | 可选,默认 v1。 |
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");
}
Webhook 用于把验证结果、风险事件、异常调用推送到业务系统,适合审计、风控联动和告警。
控制台选择应用后进入 Webhook 配置,填写回调 URL 和 Webhook Secret。平台推送时会携带签名,业务侧应校验后再入库。
{
"event": "captcha.verified",
"appId": "tac_xxxxx",
"scene": "login",
"captchaType": "SLIDER",
"riskLevel": "low",
"ip": "203.0.113.10",
"createdAt": "2026-06-15T00:00:00.000Z"
}
上线前至少完成密钥保护、域名限制、缓存策略、日志监控和异常回滚准备。
有安全审计要求时,可使用固定版本 SDK、SHA256、SRI 和自托管方式。固定版本文件发布后不覆盖,便于审计留档。
可信存证是旁路审计能力,用来证明日志批次在某个时间点形成过一致的哈希摘要,不影响实时验证码链路。
用户控制台只展示最新区块高度、区块 Hash、批次 Root、Payload Hash、平台签名状态、锚定摘要,并提供公开验真凭证 JSON 下载。
完整区块浏览器、批次列表、锚定操作和运维复核入口保留在平台后台。
凭证包含区块 Hash、Prev Hash、批次 Root、Payload Hash、记录数量、平台公钥、签名、锚定摘要和复核结果。
凭证不包含原始调用日志、用户隐私数据、后台批次明细或平台私钥。
每个公开区块带有上一块 Hash、批次 Root 和 Payload Hash,便于发现后续篡改或缺块。
平台使用 Ed25519 对区块 Hash 签名,凭证提供公钥指纹和公钥,便于外部复核。
当前支持记录外部锚定摘要;是否接入独立节点、时间戳服务或第三方链,应按业务审计需求单独配置。
业务侧应把错误码转成明确可操作的提示,避免只展示原始英文。
| 错误码 | 含义 | 建议处理 |
|---|---|---|
answer_invalid | 答案或行为轨迹不匹配。 | 提示用户重新验证,不要直接切 JS 预检放行。 |
captcha_expired | 挑战已过期或 token 被重复消费。 | 重新生成挑战,检查是否重复提交。 |
app_invalid | App ID 不存在、被禁用或域名不匹配。 | 检查应用配置和域名白名单。 |
quota_exceeded | 套餐额度不足或已到期。 | 提醒续费、购买套餐或增量包。 |
rate_limited | 请求频率过高。 | 降低重试频率,检查是否存在脚本刷接口。 |
signature_invalid | 签名、时间戳或 nonce 不合法。 | 检查签名规范串、服务器时间和密钥。 |
常见接入问题集中在域名、缓存、密钥位置和二次校验流程。
可以,但需要本地页面能访问公网 TAC 服务,并在应用里配置允许的 localhost 或测试域名。纯内网且无法访问外网会失败。
HTML、/sdk/tac.js、/sdk/manifest.json 和验证码 API 不建议长期缓存。图片素材可缓存,验证接口不能缓存。
前端环境不可信,token 必须由业务服务端拿 App Secret 校验,才能防止伪造成功回调。
先看控制台调用日志、应用配置、域名白名单、风控记录和 Webhook 推送,再结合业务侧请求 ID 排查。