<script src="https://tac.ptab.cn/sdk/tac.js"></script>
<button id="loginBtn">登录</button>
<script>
const tac = new TacCaptcha({
appId: "your_app_id",
apiBase: "https://tac.ptab.cn",
type: "SLIDER",
onSuccess(result) {
fetch("/api/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ captchaToken: result.token })
});
}
});
document.getElementById("loginBtn").onclick = () => tac.show();
</script>
TAC-SaaS 开发者文档中心
把接入路径、SDK 参数、服务端二次校验、API、Webhook、安全上线检查拆成独立模块。新接入优先看快速接入,已上线项目可直接查 API、错误码和安全建议。
按任务进入
不是从头读完整页,按你当前要做的事进入对应模块。
快速接入
标准路径是前端完成行为验证,业务后端拿 token 做二次校验,通过后再执行登录、注册、下单等动作。
/sdk/tac.js,不要把密钥写到浏览器。second-verify,成功后再处理业务请求。前端 onSuccess 只代表用户完成了挑战,最终是否允许登录、注册、下单,必须以业务后端的 /api/v1/captcha/second-verify 结果为准。
前端 SDK
SDK 负责展示验证弹窗、采集交互轨迹、提交答案,并把成功 token 交给业务页面。
发布通道
普通业务使用稳定入口 /sdk/tac.js。安全审计、自托管或 SRI 场景使用固定版本 /sdk/tac-vXX.js。
当前最新固定版本:自动同步中
支持的验证方式
| 参数 | 类型 | 说明 |
|---|---|---|
appId | string | 控制台创建应用后获得,前端可见。 |
type | string | 验证方式,可由应用配置或初始化参数指定。 |
apiBase | string | 默认使用当前站点,也可以指定 https://tac.ptab.cn。 |
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"}'
验证码 API
普通网站接入优先使用 SDK 和 second-verify;下面接口用于服务端、插件和高级集成。
POST/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":"SLIDER","scene":"login"}'返回内容
返回 challenge ID、图片/任务数据、challengeToken、推荐验证类型和风控提示信息。
POST/api/v1/captcha/verifySDK 内部›
适用场景
SDK、插件或特殊客户端集成。public 模式必须带 generate 返回的 challengeToken;secret 模式需要签名。
成功结果
返回一次性 captcha token,业务后端还需要调用 second-verify 才能放行业务动作。
POST/api/v1/captcha/second-verify后端推荐›
请求头
X-App-Id 和 X-App-Secret 必填。高安全业务可叠加签名头。
响应
code=200 表示通过;其他结果应阻断或进入人工/降级流程。
POST/api/v1/app/create用户登录›
接口签名
如果业务后端直接调用需要签名的接口,按下面规范生成签名。普通 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 sign(method, path, timestamp, nonce, body, secret) {
const normalized = [
method.toUpperCase(),
path,
String(timestamp),
nonce,
JSON.stringify(body || {})
].join("\n");
return crypto
.createHmac("sha256", secret)
.update(normalized)
.digest("base64url");
}
Webhook
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"
}
上线安全检查
上线前至少完成密钥保护、域名限制、缓存策略、日志监控和异常回滚准备。
必须完成
- App Secret 只保存在业务后端,不下发到浏览器或客户端。
- 配置允许域名,阻止未知来源生成挑战。
- 所有业务动作都以 second-verify 结果为准。
- 验证码接口、SDK manifest、HTML 页面不做长期 CDN 缓存。
- 保留调用日志、Webhook 推送和业务审计日志。
企业审计
有安全审计要求时,可使用固定版本 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 不合法。 | 检查签名规范串、服务器时间和密钥。 |
FAQ
常见接入问题集中在域名、缓存、密钥位置和二次校验流程。
本地项目能否验证?
可以,但需要本地页面能访问公网 TAC 服务,并在应用里配置允许的 localhost 或测试域名。纯内网且无法访问外网会失败。
CDN 缓存怎么配?
HTML、/sdk/tac.js、/sdk/manifest.json 和验证码 API 不建议长期缓存。图片素材可缓存,验证接口不能缓存。
为什么要二次校验?
前端环境不可信,token 必须由业务服务端拿 App Secret 校验,才能防止伪造成功回调。
线上如何排查异常?
先看控制台调用日志、应用配置、域名白名单、风控记录和 Webhook 推送,再结合业务侧请求 ID 排查。