拓冰建站拓冰建站
首页 / 资讯中心 / 正文

NocoBase 短信验证码(SMS OTP)实战指南:从添加验证器、服务商配置到自定义扩展

NocoBase 短信验证码SMS OTP实战指南从添加验证器、服务商配置到自定义扩展【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase短信验证码SMS OTP是 NocoBase 验证管理Verification插件内置的验证类型用于生成一次性动态密码OTP并通过短信下发给用户支撑短信验证码登录、双因素身份认证2FA等场景。本文基于 NocoBase 官方文档 验证短信 与nocobase/plugin-verification插件源码完整覆盖「添加验证器 → 管理员配置服务商 → 用户绑定/解绑 → 验证与安全机制 → 扩展自定义短信服务商」的全流程并给出源码级的实现依据与错误处理细节。功能背景验证管理中心中的 SMS OTP从1.6.0-alpha.30开始NocoBase 原来的「验证码」功能升级为「验证管理」管理员可以在验证管理中心接入不同的用户身份验证方式用户在个人验证管理中绑定对应的验证方式后即可在绑定了该验证器的验证场景如短信登录、2FA中进行身份验证。在验证管理中心中sms-otp是与totpTOTP 认证器并列的默认验证类型。用户认证模块如短信登录依赖验证模块提供的验证器验证模块则负责登录之外的各种风险操作场景下的身份验证。整体架构可参考 验证管理。从源码结构看服务端插件入口位于 Plugin.ts其中smsOTPProviderManager短信服务商注册器与verificationManager验证场景注册器是 SMS OTP 功能的两个核心注册点。添加短信验证器进入「验证管理」页面系统管理 → 验证管理。点击「添加」在验证类型列表中选择SMS OTP。按提示选择短信服务商并填写服务商配置见下一节保存后即可启用。对应地客户端为 sms-otp 验证类型注册了三类界面组件验证表单VerificationForm、管理员配置表单AdminSettingsForm和绑定表单BindForm见 sms/index.tsexport const smsOTPVerificationOptions { components: { VerificationForm, AdminSettingsForm, BindForm, }, };管理员配置服务商、密钥与短信模板在验证器的管理员配置中目前内置支持两家短信服务商见 sms.md阿里云短信腾讯云短信短信模板参数要求在服务商管理后台配置短信模板时必须为验证码预留参数位阿里云配置示例您的验证码为${code}腾讯云配置示例您的验证码为{1}这一点与源码实现严格对应发送验证码时data只包含code字段。阿里云实现将参数以 JSON 形式传给templateParam腾讯云实现将code作为第一个模板参数TemplateParamSet: [data.code]见 sms-aliyun.ts 与 sms-tencent.ts。各服务商的配置字段从两个内置服务商的构造函数读取的配置项来看管理员配置表单需要填写的字段如下阿里云sms-aliyun字段说明accessKeyId阿里云 AccessKey IDaccessKeySecret阿里云 AccessKey Secretendpoint短信服务 API 域名sign短信签名名称映射到signNametemplate短信模板 Code映射到templateCode腾讯云sms-tencent字段说明secretId/secretKey腾讯云 API 凭证region地域endpointAPI 接入域名SignName短信签名TemplateId短信模板 IDSmsSdkAppId应用 SDK AppID服务端在实例化服务商前会先对settings做一次app.environment.renderJsonTemplate(settings)渲染见 sms/index.ts 中的getProvider()因此配置项支持全局变量Global Variable写法——这也是客户端配置表单使用TextAreaWithGlobalScope组件的原因。用户绑定与解绑添加验证器后用户可以在「个人 → 验证管理」中绑定验证手机号填写手机号 → 获取短信验证码 → 输入验证码完成绑定。绑定成功后即可在绑定了该验证器的验证场景中进行身份验证。解绑手机号时需要通过已绑定的验证方式先完成一次身份验证防止手机号被恶意解绑。源码层面绑定动作由OTPVerification.bind()完成它会先以verifiers:bind动作走一遍完整的验证码校验流程再落库见 otp-verification/index.tsasync bind(userId: number, resource?: string, action?: string): Promise{ uuid: string; meta?: any } { const { uuid, code } this.ctx.action.params.values || {}; await this.verify({ resource: resource || verifiers, action: action || bind, boundInfo: { uuid }, verifyParams: { code }, }); return { uuid }; }绑定信息中的uuid字段即手机号本身服务端对外展示时会做脱敏处理——只保留末 4 位其余以*填充getPublicBoundInfo()。绑定手机号时会执行validateBoundInfo()手机号为空时抛出「Not a valid cellphone number, please re-enter」错误。验证流程与安全机制源码解析验证码的生成与下发smsOTP资源的create/publicCreate动作负责下发验证码见 sms-otp.ts关键逻辑参数校验请求需携带verifier验证器名称和action验证场景动作名格式为resource:action服务端校验两者在验证器表与验证场景注册表中均存在否则返回 400。防重发限流若同一接收人receiver在当前场景下已存在未使用且未过期的验证码记录则直接返回 429RateLimit并提示剩余冷却秒数。生成 6 位数字验证码randomInt(999999)转字符串并padStart(6, 0)补齐 6 位。调用服务商发送await provider.send(receiver, { code })成功后写入otpRecords表randomUUID主键、action、receiver、code、expiresAt、status、verifierName返回{ id, expiresAt }。验证码校验与防暴力破解OTPVerification.verify()的校验逻辑见 otp-verification/index.ts有效期默认expiresIn 120秒查找记录时要求expiresAt晚于当前时间单次有效记录status必须为CODE_STATUS_UNUSED校验成功后由onActionComplete()将其更新为CODE_STATUS_USED不可重复使用失败次数限制以${resource}:${action}:${receiver}为键在缓存中计数maxVerifyAttempts 5连续失败超过 5 次后返回 429「Too many failed attempts. Please request a new verification code」并提示用户重新获取校验成功后立即counter.reset(key)清零缓存 TTL 会取该验证码剩余有效期保证计数随验证码一起过期。错误映射发送阶段provider.send()抛错时按错误名映射为不同的 HTTP 响应服务商抛出的错误含义接口响应InvalidReceiver手机号不合法如阿里云isv.MOBILE_NUMBER_ILLEGAL、腾讯云InvalidParameterValue.IncorrectPhoneNumber400InvalidReceiverRateLimit服务商侧频控如阿里云isv.BUSINESS_LIMIT_CONTROL、腾讯云各类LimitExceeded.*429其他未知发送失败详情仅记录到日志不暴露给用户500验证 API 与数据表对扩展插件或前端调用方而言SMS OTP 相关接口为POST /api/smsOTP:create及匿名可用的smsOTP:publicCreatevalues支持verifier验证器名、action场景动作、uuid接收手机号登录等匿名场景使用。verifiers表保存管理员创建的验证器名称、标题、验证类型sms-otp、options中的provider与settingsotpRecords表保存每一次下发的验证码记录receiver、code、expiresAt、status、verifierName见 otp-records.ts。扩展自定义短信服务商除阿里云与腾讯云外开发者可以插件形式扩展其他短信服务商官方开发文档见 扩展短信服务商。核心分两步客户端注册服务商配置表单用户选择该服务商类型后展示的配置表单需要开发者自行注册通过plugin.smsOTPProviderManager.registerProvider(name, { components: { AdminSettingsForm } })完成表单字段可参考内置的AliyunSettings/TencentSettingsclient/otp-verification/sms。服务端实现 SMSProvider 并注册验证插件已封装创建 OTP 的完整流程开发者只需继承SMSProvider基类定义见 providers/index.ts实现与服务商交互的发送逻辑class CustomSMSProvider extends SMSProvider { constructor(options) { super(options); // options 为客户端表单提交的配置对象 const { accessKeyId, accessKeySecret, endpoint } this.options; // ... } async send(phoneNumber: string, data: { code: string }) { // 调用第三方短信 API 发送验证码 // 建议抛错时设置 error.name // InvalidReceiver → 映射为 400 手机号不合法 // RateLimit → 映射为 429 频控 } }然后通过registerProvider注册注意客户端与服务端的 name 必须一致import { Plugin } from nocobase/server; import PluginVerificationServer from nocobase/plugin-verification; import { tval } from nocobase/utils; class PluginCustomSMSProviderServer extends Plugin { async load() { const plugin this.app.pm.get(verification) as PluginVerificationServer; plugin.smsOTPProviderManager.registerProvider(custom-sms-provider-name, { title: tval(Custom SMS provider, { ns: namespace }), provider: CustomSMSProvider, }); } }服务端SMSOTPVerification.getProvider()会按验证器options.provider从smsOTPProviderManager.providers中取出对应类并用渲染后的settings实例化因此只要注册名与管理员在验证器中选择的 provider 一致即可被调用。测试用例验证官方测试 verify.test.ts 使用一个MockSMSProvider注册为mock服务商覆盖了上述全部安全机制调用smsOTP:create后otpRecords中出现对应记录status: 0未使用同一手机号在未使用验证码有效期内重复请求返回 429错误验证码返回 400「Verification code is invalid」正确验证码校验通过记录状态更新为 1已使用将记录expiresAt置为过期后校验同样返回 400连续 6 次错误校验中前 5 次 400、第 6 次起 429且此时正确验证码也无法通过需重新获取。总结NocoBase 的短信验证能力围绕「验证器 场景动作」两个抽象组织管理员在验证管理中创建 SMS OTP 验证器并配置阿里云/腾讯云密钥与模板用户绑定手机号后即可在短信登录、2FA 等场景使用底层则通过 6 位数字验证码、120 秒有效期、单次有效、5 次失败锁定与服务商频控映射构成了完整的防暴力破解链路。扩展新的短信服务商只需实现SMSProvider.send()并在两端registerProvider注册即可无缝接入现有验证体系。【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门