Logto 云片(Yunpian)短信连接器接入实战:从 API Key 申请到验证码登录全流程

发布时间:2026/9/14 13:04:41
Logto 云片(Yunpian)短信连接器接入实战:从 API Key 申请到验证码登录全流程 Logto 云片Yunpian短信连接器接入实战从 API Key 申请到验证码登录全流程【免费下载链接】logto‍ Authentication and authorization infrastructure for SaaS and AI apps, built on OIDC and OAuth 2.1 with multi-tenancy, SSO, and RBAC.项目地址: https://gitcode.com/GitHub_Trending/lo/logto本文是一份基于 Logto 开源仓库中connector-yunpian-sms官方连接器的完整接入指南面向需要在 SaaS 或 AI 应用中启用短信验证码注册/登录的开发者。读完本文你将掌握云片平台侧签名与模板的申请流程、Logto 控制台中的配置项含义以及连接器底层如何完成号码格式化、模板渲染与错误处理从而在生产环境一次配置成功。连接器概览Logto 如何通过云片发送短信云片Yunpian是国内常用的通信服务提供商提供短信、语音等多种服务。Logto 团队为其开发了官方短信连接器SMS Connector使 Logto 终端用户能够通过短信验证码完成注册与登录。该连接器位于仓库的 packages/connectors/connector-yunpian-sms 目录是 Logto 连接器体系中的SmsConnector类型实现。从源码结构看连接器的核心职责清晰接收 Logto 认证流程下发的验证码消息请求将配置中的短信模板渲染为最终文案再通过云片 HTTP API 将短信发送到目标手机号。整个发送链路由 src/index.ts 中的sendMessage函数完成配置校验由 src/types.ts 中的 Zod guard 承担连接器元数据与表单定义则集中在 src/constant.ts。本文同时存在官方英文文档与官方中文文档本文内容与之一致并补充了源码级实现细节。第一步注册云片账号并完成实名认证在配置 Logto 之前需要先在云片平台开通短信服务能力访问云片官方网站注册账号按照平台指引完成实名认证未完成实名认证的账号无法正常发送短信登录云片控制台准备后续的 API Key 获取与模板申请操作。第二步获取 API KeyAPI Key 是连接器调用云片短信接口的身份凭证获取步骤如下登录云片控制台进入「账户设置」→「子账号管理」找到并复制 API Key。在 Logto 侧配置时该值将填入apikey字段。从 src/types.ts 的配置校验规则可以看出apikey是必填字符串缺少或为空都会导致配置校验失败export const yunpianSmsConfigGuard z.object({ apikey: z.string(), templates: z .array(templateGuard) .refine( (templates) [Register, SignIn, ForgotPassword, Generic].every((type) templates.map((template) template.usageType).includes(type) ), { message: Must provide all required template types (Register/SignIn/ForgotPassword/Generic), } ), enableInternational: z.boolean().optional(), unsupportedCountriesMsg: z.string().optional(), });第三步在云片控制台配置短信签名与模板短信模板需要与云片平台审核通过的内容完全一致否则发送会被拒绝。申请流程如下在云片控制台进入「国内短信」→「签名报备」创建并提交签名等待运营商审核通过进入「国内短信」→「模板报备」模板类型选择「验证码」创建验证码模板必须包含#code#变量也可以直接选用平台的「常用模板」来加速审核流程等待模板审核通过如果还需要发送国际短信重复上述步骤但需要选择「国际短信」→「模板报备」。理解#code#与{{code}}的差异这是本连接器最容易踩坑的地方官方文档在注意事项中明确强调云片平台模板中的验证码变量占位符是#code#而 Logto 连接器配置中的变量占位符是{{code}}。两者并不冲突#code#是云片侧用于识别变量的语法用于通过平台审核Logto 连接器负责把最终渲染好的完整文案即模板内容中{{code}}被替换为真实验证码后的字符串发给云片云片按整条文案发送不再做二次变量替换。因此你在云片后台看到的模板变量形式是#code#在 Logto 配置里写的内容则使用{{code}}。从 packages/toolkit/connector-kit/src/index.ts 的replaceSendMessageHandlebars实现可以看出Logto 使用 Handlebars 风格的{{key}}语法完成模板渲染渲染所需的 payload 数据如code由 Logto 认证流程自动注入。渲染逻辑在 src/index.ts 中通过replaceSendMessageHandlebars(template.content, payload)调用const template getConfigTemplateByType(type, config); assert( template, new ConnectorError( ConnectorErrorCodes.TemplateNotFound, No SMS template found for type ${type} ) ); const messageContent replaceSendMessageHandlebars(template.content, payload);其中getConfigTemplateByType会根据消息类型如Register、SignIn、ForgotPassword、Generic从配置的templates数组中选出对应usageType的模板如果找不到会抛出TemplateNotFound错误。完整的模板类型枚举TemplateType定义在 packages/toolkit/connector-kit/src/types/passwordless.ts除上述四种基础类型外还包含OrganizationInvitation、UserPermissionValidation、BindNewIdentifier、MfaVerification、BindMfa等更多场景。第四步在 Logto 控制台配置连接器配置入口与步骤登录 Logto 控制台进入「连接器」Connectors页面找到并点击「云片短信服务」YunPian SMS Service填写配置表单API Key填写从云片控制台获取的 API KeySMS 模板按使用场景配置模板确保与云片已审核通过的模板内容完全一致。表单字段详解与默认值根据 src/constant.ts 中的formItems定义连接器表单共包含四个配置项配置项类型必填默认值说明apikey文本是无云片控制台获取的 API KeytemplatesJSON是见下方默认模板按usageType组织的短信模板数组必须包含Register、SignIn、ForgotPassword、Generic四种类型enableInternational开关否false是否启用国际短信启用时需同步申请国际模板unsupportedCountriesMsg文本否The administrator has not enabled international SMS services.手机号不受支持时向用户展示的提示文案留空则不返回错误templates字段在控制台中以下方 JSON 结构保存默认值示例模板内容与云片审核通过的内容保持一致[ { usageType: SignIn, content: 您的验证码是 {{code}}。如非本人操作请忽略本短信 }, { usageType: Register, content: 您的验证码是 {{code}}。如非本人操作请忽略本短信 }, { usageType: ForgotPassword, content: 您的验证码是 {{code}}。如非本人操作请忽略本短信 }, { usageType: Generic, content: 您的验证码是 {{code}}。如非本人操作请忽略本短信 } ]从 src/constant.ts 可以看到该连接器的默认模板列表实际还预置了OrganizationInvitation、UserPermissionValidation、BindNewIdentifier、MfaVerification、BindMfa等多个场景的模板均使用统一的验证码文案。也就是说连接器开箱即用即可覆盖注册、登录、找回密码、组织邀请、MFA 绑定等多种消息场景。底层实现解析号码格式化与国际化策略连接器在发送前会对手机号做规范化处理相关逻辑位于 src/index.tsisChinaPhoneNumber使用正则/^(\?86)1[3-9]\d{9}$/判断号码是否为带86或86前缀的中国大陆手机号formatPhoneNumber会先去除所有空白字符然后若是86或86开头的中国号码截取末尾 11 位作为mobile参数云片国内短信要求不带国家码若号码不是中国格式且不以开头则自动补上前缀国际号码格式。发送前的国际化判断逻辑如下if (!enableInternational formattedPhone.startsWith()) { if (unsupportedCountriesMsg) { throw new ConnectorError(ConnectorErrorCodes.General, unsupportedCountriesMsg); } else { console.warn(connector-yunpian-sms: unsupported phone number: ${formattedPhone}); return; } }即未开启enableInternational时一旦发现号码被格式化为开头的国际号码连接器会抛出配置的unsupportedCountriesMsg错误若该字段留空则仅打印警告并静默返回不实际发送短信。底层实现解析请求构造与错误处理连接器通过云片的单条发送接口发送短信接口地址定义在 src/constant.tsexport const endpoint https://sms.yunpian.com/v2/sms/single_send.json;请求以application/x-www-form-urlencoded表单形式提交三个字段见 src/types.ts 中的YunpianSmsPayload字段说明apikey云片 API Keymobile格式化后的手机号text渲染完成的短信全文同时请求头设置Accept: application/json;charsetutf-8期望云片返回 JSON。错误处理方面连接器捕获请求异常当云片返回 HTTP 400 时会解析响应体中的错误 JSON字段包括http_status_code、code、msg、可选的detail对应 src/types.ts 中的yunpianErrorResponseGuard并将msg转为ConnectorError(ConnectorErrorCodes.General, ...)抛出便于 Logto 侧定位失败原因。测试验证与质量保障该连接器配套了完整的单元测试 src/index.test.ts使用nock拦截网络请求验证了两种核心场景连接器初始化不抛错createConnector({ getConfig })在配置合法时正常返回发送消息成功模拟云片返回code: 0发送成功的响应sendMessage({ to: 13800138000, type: TemplateType.Generic, payload: { code: 1234 } })正常完成。测试使用的模拟配置见 src/mock.ts其中apikey为a123b456c789d0模板内容与默认模板一致。开发者可以参考测试用例在本地运行pnpm test见 package.json 的 scripts 定义验证连接器行为。注意事项汇总模板内容必须与云片审核通过的模板完全一致任何字符差异包括标点、空格都可能导致发送失败云片模板中的验证码变量是#code#而 Logto 连接器配置中使用{{code}}云片会根据 API Key 自动追加默认签名因此模板内容中无需手动加入签名建议正式投入使用前先发送测试短信验证配置正确性若需发送国际短信务必同时开启enableInternational开关并提前在云片申请「国际短信」模板连接器的 Node.js 运行环境要求为^22.14.0见 package.json 的engines字段。参考资料云片官方开发文档短信接口说明、签名与模板报备指引Logto 官方 SMS 连接器配置指南连接器通用配置方法与最佳实践本仓库中其他短信类连接器如connector-aliyun-sms、connector-tencent-sms、connector-twilio-sms等的 README 与源码可作为同类集成参考连接器开发框架 packages/toolkit/connector-kit 的源码其中定义了SendMessageFunction、TemplateType、replaceSendMessageHandlebars、getConfigTemplateByType等连接器开发必需的类型与工具函数。【免费下载链接】logto‍ Authentication and authorization infrastructure for SaaS and AI apps, built on OIDC and OAuth 2.1 with multi-tenancy, SSO, and RBAC.项目地址: https://gitcode.com/GitHub_Trending/lo/logto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考