tencent cloud

验证码

Web 客户端接入

下载
聚焦模式
字号
最后更新时间: 2026-06-11 19:01:32

服务流程图



前提条件

客户端接入前,需完成新建验证,并在验证列表获取所需的 CaptchaAppId 以及 AppSecretKey。步骤如下:

1. 登录 验证码控制台,左侧导航栏选择验证管理,进入验证管理页面。
2. 单击创建验证码,根据业务场景需求,设置验证名称等参数。
3. 单击确定,完成新建验证码,即可在验证列表中查看验证码 CaptchaAppId 及 AppSecretKey。
注意:
自2024年12月起验证码提供两个版本的服务,老版本用户控制台架构保持不变,使用体验不受影响。老版本客户如需使用新版本,需新建 CaptchaAppid,以确保后续顺畅使用验证码功能。如有疑问,随时联系 联系我们

代码示例

以下代码示例,单击验证,激活验证码,并弹窗展示验证结果。
注意:
该示例未展示调用票据校验 API 的逻辑。业务客户端完成验证码接入后,业务服务端需二次核查验证码票据结果(未接入票据校验,会导致黑产轻易伪造验证结果,失去验证码人机对抗效果),详情请参见:接入票据校验(Web 及 App)
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web 前端接入示例</title>
<!-- 验证码程序依赖(必须)。请勿修改以下程序依赖,如通过其他手段规避加载,会导致验证码无法正常更新,对抗能力无法保证,甚至引起误拦截。 -->
<script src="https://ca.turing.captcha.qcloud.com/TJNCaptcha-global.js"></script>
</head>

<body>
<div id="cap_iframe"></div>
<button id="CaptchaId" type="button">验证</button>
</body>

<script>

// 定义回调函数
function callback(res) {
// 第一个参数传入回调结果,结果如下:
// ret Int 验证结果,0:验证成功。2:用户主动关闭验证码。
// ticket String 验证成功的票据,当且仅当 ret = 0 时 ticket 有值。
// CaptchaAppId String 验证码应用ID。
// bizState Any 自定义透传参数。
// randstr String 本次验证的随机串,后续票据校验时需传递该参数。
console.log('callback:', res);


// res(用户主动关闭验证码)= {ret: 2, ticket: null}
// res(验证成功) = {ret: 0, ticket: "String", randstr: "String"}
// res(请求验证码发生错误,验证码自动返回trerror_前缀的容灾票据) = {ret: 0, ticket: "String", randstr: "String", errorCode: Number, errorMessage: "String"}
// 此处代码仅为验证结果的展示示例,真实业务接入,建议基于ticket和errorCode情况做不同的业务处理
if (res.ret === 0) {
// 复制结果至剪切板
var str = '【randstr】->【' + res.randstr + '】 【ticket】->【' + res.ticket + '】';
var ipt = document.createElement('input');
ipt.value = str;
document.body.appendChild(ipt);
ipt.select();
document.execCommand("Copy");
document.body.removeChild(ipt);
alert('1. 返回结果(randstr、ticket)已复制到剪切板,ctrl+v 查看。\\n2. 打开浏览器控制台,查看完整返回结果。');
}
}

// 定义验证码js加载错误处理函数
function loadErrorCallback() {
var appid = 'CaptchaAppId';
// 生成容灾票据或自行做其它处理
var ticket = 'trerror_1001_' + appid + '_' + Math.floor(new Date().getTime() / 1000);
callback({
ret: 0,
randstr: '@'+ Math.random().toString(36).substr(2),
ticket,
errorCode: 1001,
errorMessage: 'jsload_error',
});
}

// 定义验证码触发事件
window.onload = function(){
document.getElementById('CaptchaId').onclick = function(){
try {
// 生成一个验证码对象
// CaptchaAppId:登录验证码控制台,从【验证管理】页面进行查看。如果未创建过验证,请先新建验证。
//callback:定义的回调函数
var captcha = new TencentCaptcha(document.getElementById('cap_iframe'), '你的验证码CaptchaAppId', callback, {});
// 调用方法,显示验证码
captcha.show();
} catch (error) {
// 加载异常,调用验证码js加载错误处理函数
loadErrorCallback();
}
}
}
</script>

</html>

接入说明

步骤1:动态引入验证码 JS

Web 页面需动态引入验证码 JS,在业务需要验证时,唤起验证码进行验证。
<!-- 动态引入验证码JS示例 -->
<script src="https://ca.turing.captcha.qcloud.com/TJNCaptcha-global.js"></script>
注意:
必须动态引入验证码 JS。如通过其他手段规避动态加载,会导致验证码无法正常更新,对抗能力无法保证,甚至引起误拦截。

步骤2:创建验证码对象

引入验证码 JS 后,验证码会在全局注册一个TencentCaptcha类,业务方可以使用这个类自行初始化验证码,并对验证码进行显示或者隐藏。
注意:
触发验证码的元素不要使用id="TencentCaptcha",TencentCaptcha 属于系统默认 id,不可使用。

构造函数

new TencentCaptcha(DOM, CaptchaAppId, callback, options);
参数说明
参数名
值类型
说明
DOM
Element Nodes
承载 Robot 勾选框的容器。
CaptchaAppId
String
验证码 CaptchaAppId:登录 验证码控制台,在验证管理页面进行查看。如果未创建过验证,请先新建验证。
注意:不可使用客户端类型为小程序的 CaptchaAppId,会导致数据统计错误。
callback
Function
验证码回调函数,详情请参见 callback 回调函数
options
Object
验证码外观配置参数, 详情请参见 options 外观配置参数

callback 回调函数

验证结束后,会调用业务传入的回调函数,并在第一个参数中传入回调结果。回调结果字段说明如下:
字段名
值类型
说明
ret
Int
验证结果,0:验证成功。2:用户主动关闭验证码。
ticket
String
验证成功的票据,当且仅当 ret = 0 时 ticket 有值。
CaptchaAppId
String
验证码应用 ID。
bizState
Any
自定义透传参数。
randstr
String
本次验证的随机串,后续票据校验时需传递该参数。
errorCode
Number
错误 code ,详情请参见 回调函数 errorCode 说明
errorMessage
String
错误信息。
verifyDuration
Number
验证码校验接口耗时(ms)
actionDuration
Number
用户操作校验成功耗时(ms)
sid
String
链路 sid

回调函数 errorCode 说明

errorCode
说明
1001
TJNCaptcha-global.js 加载错误。
1002
调用 show 方法超时
1003
中间 js 加载超时
1004
中间 js 加载错误
1005
中间 js 运行错误
1006
拉取验证码配置错误/超时
1007
iframe 加载超时
1008
iframe 加载错误
1009
jquery 加载错误
1010
滑块 js 加载错误
1011
滑块 js 运行错误
1012
刷新连续错误3次
1013
验证网络连续错误3次

options 外观配置参数

options 参数用于对验证码进行定制外观设置,默认可以设置为空。
注意:
验证码弹窗内部不支持调整样式大小,如果需要调整,可在弹窗最外层用 class=tcaptcha-transform 的元素设置 transform:scale();。验证码更新可能会改变元素的 id,class 等属性,请勿依赖其他验证码元素属性值覆盖样式。
如果手机原生端有设置左右滑动手势,需在调用验证码 show 方法前禁用,验证完成后再打开,防止与验证码滑动事件冲突。
配置名
值类型
说明
bizState
Any
自定义透传参数,业务可用该字段传递少量数据,该字段的内容会被带入 callback 回调的对象中。
enableDarkMode
Boolean/String
开启自适应深夜模式或强制深夜模式。
开启自适应深夜模式: {"enableDarkMode": true}
强制深夜模式: {"enableDarkMode": 'force'}
ready
Function
验证码加载完成的回调,回调参数为验证码实际的宽高:
{"sdkView": {
"width": number,
"height": number
}}
该参数仅为查看验证码宽高使用,请勿使用此参数直接设定宽高
needFeedBack
String
自定义帮助链接: {"needFeedBack": 'url 地址' }
enableAutoCheck
Boolean
开启后,对安全的请求可自动完成勾选验证,无需用户操作,默认为关闭。
开启:{"enableAutoCheck":true}
userLanguage
String
指定验证码提示文案的语言,优先级高于控制台配置。
支持传入值同 navigator.language 用户首选语言,大小写不敏感。
type
String
定义验证码展示方式。
popup(默认)弹出式,以浮层形式居中弹出展示验证码。
embed 嵌入式,以嵌入指定容器元素中的方式展示验证码。
aidEncrypted
String
CaptchaAppId 加密校验串,可选参数。详情见 CaptchaAppid 加密校验能力接入指引
showFn
Function
duration 渲染耗时 + sid 回调函数。
verifyFn
Function
用于获取每次验证校验的结果和 sid。
pass(boolean):本次校验结果,true 表示验证通过,false 表示验证未通过。
sid(string):本次校验的会话 ID。

userLanguage 配置参
数(除滑动拼图验证外,其他验证形式只支持中英文
userlanguage 参数可设置为空,即默认自适应浏览器语言。
参数名
说明
zh-cn
简体中文
zh-hk
繁体中文(中国香港)
zh-tw
繁体中文(中国台湾)
en
英文
en-in
英语(印度)
ar
阿拉伯语
cs-cz
捷克语(捷克)
de
德语
es
西班牙语
es-la
西班牙语(拉丁美洲)
fr
法语
fil
菲律宾
he
希伯来语
hi
印地语
id
印尼语
it
意大利语
ja
日语
ko
朝鲜语
lo
老挝语
ms
马来语
my
缅甸语
nl
荷兰语
pl
波兰语
pt
葡萄牙语
pt-pt
葡萄牙语(葡萄牙)
ro-ro
罗马尼亚语(罗马尼亚)
ru
俄语
th
泰语
tr
土耳其语
uk-ua
乌克兰语(乌克兰)
ur
乌尔都语
vi
越南语

步骤3:调用验证码实例方法

TencentCaptcha 的实例提供一些操作验证码的常用方法:
方法名
说明
传入参数
返回内容
show
显示验证码,可以反复调用。
destroy
隐藏验证码,可以反复调用。
getTicket
获取验证成功后的 ticket。
Object:{"CaptchaAppId":"","ticket":""}
reload
重新初始化勾选框,可以反复调用。

步骤4:容灾处理

为保障验证码 Captcha 服务端异常时不阻塞客户网站正常业务流程,建议参考如下方式接入验证码。
1. 定义 JS 加载错误处理函数。
// 错误处理函数作用:在JS加载或初始化错误时,保障事件流程正常
// 函数定义需在script加载前
function loadErrorCallback() {
var appid = ''
// 生成容灾票据或自行做其它处理
var ticket = 'trerror_1001_' + appid + Math.floor(new Date().getTime() / 1000);
callback({
ret: 0,
randstr: '@'+ Math.random().toString(36).substr(2),
ticket,
errorCode: 1001,
errorMessage: 'jsload_error',
});
}
2. 调用验证码实例 catch 到错误时,调用 JS 加载错误处理函数。
try {
// 生成一个验证码对象
var captcha = new TencentCaptcha(document.getElementById('cap_iframe'), '你的验证码CaptchaAppId', callback, {});
// 调用方法,显示验证码
captcha.show();
} catch (error) {
// 加载异常,调用验证码js加载错误处理函数
loadErrorCallback();
}
3. 定义验证码 callback 回调函数时,根据 ticket 和 errorCode (而非 ret)的情况做处理。errorCode 的定义参考步骤2中"回调函数 errorCode 说明"。
function callback(res) {
// res(用户主动关闭验证码)= {ret: 2, ticket: null}
// res(验证成功) = {ret: 0, ticket: "String", randstr: "String"}
// res(请求错误,返回trerror_前缀的容灾票据) = {ret: 0, ticket: "String", randstr: "String", errorCode: Number, errorMessage: "String"}
if (res.ticket){
//根据errorCode情况做特殊处理
if(res.errorCode === xxxxx){
//自定义容灾逻辑(例如跳过这次验证)
}
}
}
完整容灾方案,详情请见业务容灾方案
注意:
业务客户端完成验证码接入后,服务端需二次核查验证码票据结果(未接入票据校验,会导致黑产轻易伪造验证结果,失去验证码人机对抗效果),详情请参见:接入票据校验(Web 及 App)


CaptchaAppid 加密校验能力接入指引

通过前端传递加密符(非必选能力,可根据安全性需求选择性接入),可以有效防止因 CaptchaAppid 泄露而造成的资源盗刷。

加密规则

接口通过 aidEncrypted 参数(即加密后的字符串标识),支持采用加密模式传递验证码业务 CaptchaAppid 进行校验。
当控制台强制校验开启时,触发加密模式。由客户的服务端进行加密后下发对应加密字符串到客户的前端,由客户前端将加密后的字符串传参到验证码侧。
加密步骤如下:
1. 登录 验证码控制台,左侧导航栏中,选择验证管理 > 验证码详情,单击集成
2. 在验证管理页面,选择所需 AppSecretKey,作为密钥 key。当 key 小于32字节时,循环填充同一个 AppSecretKey 补齐到32字节作为密钥 key。

3. 随机生成16字节的 IV,结合步骤1中得到的密钥 Key,对业务数据对象进行 AES256加密,加密模式为 CBC/PKCS7Padding,加密的业务数据对象为验证码业务 CaptchaAppid&时间戳&密文过期时间,时间戳为秒级当前 unix 时间戳,不可为未来时间,密文过期时间单位为秒最大值为86400秒,得到加密后的串为 CaptchaAppidEncrypted。
4. 对步骤2中 IV 拼接 AES256加密得到的字节数组 CaptchaAppidEncrypted 进行 Base64编码,即 Base64(IV+CaptchaAppidEncrypted),中间无连接符,得到最终加密后的业务参数请求字符串即为 aidEncrypted。
5. 关于验证码加密处理的有效时间,过期时间可由客户根据自身需求自行设置。在此需要提醒的是,验证码从开始加载便启动计时机制。若所设定的计时时长过短,可能出现这样的情况:验证码加载完成后,用户在一段时间内并未进行操作,而当用户后续执行相关操作时,验证码对应的加密信息已过期失效。

加密结果示例

类型
示例值
CaptchaAppid
123456789
时间戳
1710144972
过期时间
86400秒
iv
0123456789012345
AppSecretKey
1234567891011121314151516
循环填充的密钥 key
12345678910111213141515161234567
加密的业务数据对象
123456789&1710144972&86400
加密后的最终字符串 aidEncrypted
MDEyMzQ1Njc4OTAxMjM0NWvZ11atw+1uzYmoIyt5rAQVPyMK9ZDavskPw5hcayeT

代码示例

服务端加密
加密规则为:Base64(IV + AES256(CaptchaAppid&时间戳&密文过期时间,IV, Key) ),即使用随机生成16字节的 IV、及根据 AppSecretKey 循环填充后得到32字节的加密 Key,使用 AES256算法加密模式 CBC/PKCS7Padding,对明文数据 CaptchaAppid&时间戳&密文过期时间进行加密。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
import time


def encrypt(plaintext, key, iv):
cipher = AES.new(key, AES.MODE_CBC, iv) # 创建一个新的AES cipher,CBC模式
ciphertext = cipher.encrypt(pad(plaintext.encode(), AES.block_size))# 对数据进行填充,然后加密。pad(plaintext.encode(), AES.block_size)将检查明文长度是否为16字节倍数,若非16字节倍数,将使用PKCS7填充方式将明文填充到16字节倍数。
ciphertextBase64 = base64.b64encode(iv + ciphertext).decode('utf-8') # iv拼接加密后的数据,并进行Base64返回后进行传输。
return ciphertextBase64


# 加密示例
AppSecretKey = b'1234567891011121314151516' #客户从控制台获取对应验证码账号下的AppSecretKey,25位
remainder = 32 % AppSecretKey.__len__() # 计算需要补充的密钥长度
key = AppSecretKey + AppSecretKey[:remainder] # 最终加密key,补充满32位。

Captchaappid = "123456789" # 客户自身的验证码CaptchaAppid
curTime = 1710144972 # 获取当前的时间戳,示例暂设置成固定时间戳,客户应该设置成最新的时间戳,使用int(time.time())
expireTime = 86400 # 过期时间设置,这里暂设置成该值,客户根据自身需要设置

plaintext = Captchaappid + "&" + str(curTime) + "&" + str(expireTime) # 拼接待加密的业务数据对象,CaptchaAppid&时间戳&密文过期时间

iv = "0123456789012345".encode() # 随机生成16字节的IV,这里暂设置成该值,客户使用时应该用随机生成的数据,使用os.urandom(16)

ciphertext = encrypt(plaintext, key, iv) # 加密
print("Ciphertext (Base64):", ciphertext) # 本示例数据将输出MDEyMzQ1Njc4OTAxMjM0NWvZ11atw+1uzYmoIyt5rAQVPyMK9ZDavskPw5hcayeT



前端接入示例


const encryptAppid = async () => {
/** 从后端获取加密后的 appid字符串 */
const { aidEncrypted } = await fetch('/api/encryptAppid');
/** 回调函数 */
const callBack = (ret) => {
console.log('ret', ret);
};
/** 错误回调函数 */
const errorCb = (error) => {
console.log('error', error);
};
try {
/** 将获取的加密字符串传入aidEncrypted参数 */
const captcha = new TencentCaptcha('123456789', callBack, { aidEncrypted: aidEncrypted });
captcha.show();
} catch (error) {
errorCb(error);
}
};

常见问题

详情参见 接入相关问题

帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈