13
AI 验证码是壹盾安全自研的智能人机验证服务,为网站关键业务接口(登录、注册、支付等)提供人机识别保护。验签在 CDN 边缘节点完成,源站无需任何改动,前端嵌入轻量 JS SDK 即可接入。
核心特性:
- 边缘验签,零改后端 — 所有验证逻辑在 CDN 节点完成
- 五种验证形态 — 滑块、文字点选、旋转、拼图、一点即过
- 一次性 Token — 默认 90 秒有效,用后即焚,绑定 IP 和设备
- 实时统计 — 调用量、通过率、失败率、封禁数一目了然
适用场景
| 场景 | 推荐类型 |
|---|---|
| 账号登录 / 注册 | 滑块验证 / 一点即过 |
| 短信验证码发送 | 滑块验证 |
| 在线投票 | 文字点选 / 旋转验证 |
| 评论发帖 | 一点即过 |
| 优惠领取 / 抢购 | 拼图验证 / 文字点选 |
| 文件下载 / API 调用 | 滑块验证 / 一点即过 |
接入步骤
第一步:添加验证规则
进入站点配置 → AI 验证码 → 点击「添加规则」,填写:
- 规则名称 — 如「登录接口验证」
- URI 模式 — 需要保护的路径,如
/api/login - 匹配类型 — 精确匹配 / 前缀匹配 / 正则匹配
- 请求方法 — GET、POST、PUT、DELETE(可多选)
- 验证码类型 — 五种类型选其一
保存后复制生成的场景 ID(sc_ 开头),前端 SDK 初始化时需要。
第二步:嵌入 JS SDK
HTML 接入:
html<script src="https://你的域名/_seton/captcha-sdk.js"></script>
<div id="captcha-box"></div>
<button id="login-btn">登录</button>
<script>
SetonCaptcha.init({
sceneId: '你的场景ID',
mode: 'popup',
element: '#captcha-box',
button: '#login-btn',
onSuccess(token) {
fetch('/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Seton-Captcha-Token': token
},
body: JSON.stringify({ username, password })
})
}
})
</script>
React 接入:
javascriptuseEffect(() => {
const s = document.createElement('script')
s.src = '/_seton/captcha-sdk.js'
s.onload = () => window.SetonCaptcha.init({
sceneId: '你的场景ID',
mode: 'popup',
element: '#captcha-box',
button: '#login-btn',
onSuccess: (token) => { /* 带 X-Seton-Captcha-Token 请求业务接口 */ }
})
document.head.appendChild(s)
}, [])
Vue 接入:
javascriptonMounted(() => {
const s = document.createElement('script')
s.src = '/_seton/captcha-sdk.js'
s.onload = () => window.SetonCaptcha.init({
sceneId: '你的场景ID',
mode: 'popup',
element: '#captcha-box',
button: '#login-btn',
onSuccess: (token) => { /* 带 X-Seton-Captcha-Token 请求业务接口 */ }
})
document.head.appendChild(s)
})
第三步:处理验证结果
验证通过后 SDK 回调返回 Token,前端通过 X-Seton-Captcha-Token 请求头携带即可。节点在响应头 X-Seton-Captcha-Code 中返回验签结果。
SPA 前后端分离接入
SPA 架构推荐 Axios 自动拦截器,业务代码完全无感知:
javascript// captchaInterceptor.js
let pending = null
function requestToken(sceneId) {
if (pending) return pending
pending = new Promise((resolve, reject) => {
if (typeof SetonCaptcha === 'undefined') {
pending = null
return reject(new Error('SDK 未加载'))
}
try { SetonCaptcha.destroy() } catch (_) {}
SetonCaptcha.init({
sceneId: sceneId || 'default',
mode: 'popup',
onSuccess(token) { pending = null; resolve(token) },
onFail(err) { pending = null; reject(new Error(err)) },
})
SetonCaptcha.show()
})
return pending
}
export function setupCaptchaInterceptor(axios, options = {}) {
const maxRetry = options.maxRetry || 1
const headerName = options.headerName || 'X-Seton-Captcha-Token'
axios.interceptors.response.use(
(res) => res,
async (error) => {
const resp = error.response
if (!resp || resp.status !== 403) throw error
if (!resp.data || resp.data.error !== 'captcha_required') throw error
const config = error.config
config._captchaRetry = (config._captchaRetry || 0) + 1
if (config._captchaRetry > maxRetry) throw error
const token = await requestToken(resp.data.scene_id)
config.headers[headerName] = token
return axios.request(config)
}
)
}
应用入口调用一次即可:
javascriptimport axios from 'axios'
import { setupCaptchaInterceptor } from './captchaInterceptor'
setupCaptchaInterceptor(axios)
SDK 方法
| 方法 | 说明 |
|---|---|
SetonCaptcha.init(config) |
初始化,config 含 sceneId / mode / element / button / onSuccess / captchaMode |
SetonCaptcha.show() |
手动弹出验证码 |
SetonCaptcha.hide() |
隐藏 |
SetonCaptcha.refresh() |
刷新题目 |
SetonCaptcha.destroy() |
销毁实例 |
响应码
| 码 | 含义 |
|---|---|
| T001 | 验证通过 |
| F003 | Token 解析错误 |
| F005 | 场景不存在 |
| F017 | Token 被篡改 |
| F018 | Token 重复使用 |
| F019 | Token 已过期(90 秒) |
| F020 | IP/UA/站点不匹配 |
| F021 | 场景 ID 不一致 |
注意事项
- Token 一次性使用,90 秒有效,绑定 IP 和 User-Agent
- SDK 地址
/_seton/captcha-sdk.js由 CDN 节点提供,与业务同域,无跨域问题 - 建议页面加载时引入 SDK,初始化与验证间隔 2 秒以上
- Axios 拦截器内部做了并发去重,同一时刻只弹一个验证码窗口
- 拦截器仅在
403 + captcha_required时触发,不影响其他 403 的正常处理
壹盾安全官方
回复讨论
0
登录后可参与回复讨论。
当前还没有回复,欢迎成为第一个参与讨论的人。
文明发言,理性讨论