Skip to main content

验证码处理指南

本文档介绍如何在腾讯云开发身份验证中处理验证码相关逻辑,包括触发条件、错误处理和完整的实现流程。

触发条件

验证码会在以下情况下被要求输入:

  • 用户名密码登录失败 5 次后
  • 发送手机号或邮箱验证码时达到频率限制

错误信息

当需要验证码时,接口会返回相应的错误信息:

  • error == captcha_required:表示请求触发了验证码相关逻辑,需要进行机器验证
  • error == captcha_invalid:表示验证码无效,需要重新获取验证码
注意

验证码流程完成后,若业务接口返回 error 等于 captcha_required,表示请求需要 captcha_token 参数,应尽可能使用本地未过期的验证码。当 error 等于 captcha_invalid 时,表示验证码无效,需要重新获取验证码。在同一个验证流程内,captcha_invalid 最多尝试一次即可。

// 错误信息示例:
{
data: {
error: "captcha_required",
error_code: 4001,
error_description: "captcha_token required"
}
}

处理流程

完整流程

验证码处理的完整流程如下:

  1. 用户尝试登录或发送验证码
  2. 若触发验证码要求,SDK 抛出 captcha_required 错误
  3. 编写SDK适配器,捕获错误并触发 openURIWithCallback
  4. openURIWithCallback 方法中获取验证码参数,并通过 EVENT_BUS 发送给前端展示
  5. 前端展示验证码图片并等待用户输入
  6. 用户输入验证码并提交
  7. 系统验证并返回结果
  8. 根据验证结果决定是否重试原操作

关于第三步的 SDK适配器以及 openURIWithCallback 方法请参考 适配器指引

适配器实现

function genAdapter(options) {
const adapter: SDKAdapterInterface = {
captchaOptions: {
openURIWithCallback: async (url: string) => {
// 解析 URL 中的验证码参数
const { captchaData, state, token } = cloudbase.parseCaptcha(url);

// 通过事件总线发送验证码数据,进行前端缓存及展示
options.EVENT_BUS.emit("CAPTCHA_DATA_CHANGE", {
captchaData, // Base64 编码的验证码图片
state, // 验证码状态标识
token, // 验证码 token
});

// 监听验证码校验结果
return new Promise((resolve) => {
console.log("等待验证码校验结果...");
options.EVENT_BUS.once("RESOLVE_CAPTCHA_DATA", (res) => {
// auth.verifyCaptchaData 的校验结果
resolve(res);
});
});
},
},
};
return adapter;
}

初始化SDK

import cloudbase from '@cloudbase/js-sdk'

// 创建事件总线实例,具体EventBus实现可参考网上示例
const EVENT_BUS = new EventBus();

// 配置并使用适配器,将 EVENT_BUS 注入给 genAdapter
cloudbase.useAdapters(adapter, { EVENT_BUS });

const app = cloudbase.init({
env: '环境ID',
appSign: '应用标识',
appSecret: {
appAccessKeyId: '应用凭证版本号',
appAccessKey: '应用凭证'
}
});

const auth = app.auth();

验证码界面实现

// 存储当前验证码状态
let captchaState = {
captchaData: "", // Base64 编码的验证码图片
state: "", // 验证码状态标识
token: "", // 验证码 token
};

// 监听验证码数据变化
EVENT_BUS.on("CAPTCHA_DATA_CHANGE", ({ captchaData, state, token }) => {
console.log("收到验证码数据", { captchaData, state, token });

// 更新本地验证码状态
captchaState = { captchaData, state, token };

// 在页面中显示验证码图片,例如在 Web 中使用 img 标签展示
const captchaImage = document.getElementById('captcha-image');
if (captchaImage) {
captchaImage.src = captchaData;
}
});

// 用户点击刷新验证码时调用
const refreshCaptcha = async () => {
try {
// 获取最新验证码信息
const result = await auth.createCaptchaData({
state: captchaState.state
});

// 更新本地验证码状态
captchaState = {
...captchaState,
captchaData: result.data,
token: result.token,
};

// 更新显示的验证码图片
const captchaImage = document.getElementById('captcha-image');
if (captchaImage) {
captchaImage.src = result.data;
}
} catch (error) {
console.error("刷新验证码失败", error);
}
};

// 用户提交验证码时调用
const verifyCaptchaData = async (userCaptcha) => {
try {
// 校验验证码
const verifyResult = await auth.verifyCaptchaData({
token: captchaState.token,
key: userCaptcha
});

// 将校验结果通知适配器
EVENT_BUS.emit("RESOLVE_CAPTCHA_DATA", verifyResult);

console.log("验证码校验成功");
} catch (error) {
console.error("验证码校验失败", error);
// 校验失败时可以选择刷新验证码
await refreshCaptcha();
}
};

验证码展示效果

示例代码地址: 示例代码

验证码展示效果

相关 API

  • auth.createCaptchaData(options) - 创建验证码数据
  • auth.verifyCaptchaData(options) - 验证验证码
  • cloudbase.parseCaptcha(url) - 解析验证码 URL 参数

注意事项

  1. 验证码具有时效性,建议在获取后及时使用
  2. 同一验证流程中,验证码校验失败最多重试一次
  3. 建议在验证码校验失败后提供刷新验证码的功能
  4. 确保事件总线的正确初始化和事件监听