ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

uni-id-pages配置Email验证码全流程:SMTP与云函数避坑指南

uni-id-pages配置Email验证码全流程:SMTP与云函数避坑指南 uni-id-pages这个插件很多uni-app开发者都不陌生注册登录那套页面和云函数开箱即用。但真到自己项目里加上“配置email”这一步很多人就卡住了——不是不清楚要配SMTP而是不知道这个邮箱服务到底在哪个环节生效、uni-id发送验证码时走的是哪条链路。这篇文章就是把我自己配置uni-id-pages email、从零到能收到验证码的完整过程和踩坑记录整理出来适合正在集成uni-id-pages、需要邮箱注册/找回密码/绑定邮箱功能的uni-app开发者参考。1. 为什么uni-id-pages需要自己再配一套email1.1 uni-id-pages里的邮件从哪来uni-id-pages是uni-app生态里非常常用的一套现成用户中心登录、注册、找回密码、绑定手机、绑定邮箱这些页面和云函数都是预先封装好的。很多新手以为装上插件就能直接给用户发邮件其实不是这样。插件只是把“发送邮件验证码”这个动作接好了但真正执行发信动作的SMTP服务是没有的。DCloud也没法替你白嫖一个邮件服务器所以邮箱相关的功能要自己提供发件账号。那uni-id是怎么调用邮件服务的呢现在主流的做法是依赖uniCloud的公共模块uni-cloud-email。这个模块本质上是把Node.js的邮件发送能力封装了一层配置好SMTP后uni-id-co云对象里内置的sendEmailCode等方法会自动调用它把验证码发到用户邮箱。也就是说你要做的不是改业务代码而是把uni-cloud-email这个“邮局窗口”对接上你自己的邮箱账号。理解这一点后面的配置就顺了。我当时第一次配置的时候也纠结过是不是要改云函数源码后来翻了下uni-id-co的依赖才发现它已经默认引用了uni-cloud-email。所以正常情况下你只要把公共模块的配置填对云函数不需要改一行代码。1.2 短信和邮件怎么选邮箱验证码和短信验证码在很多场景下是互补的。之前我做过一个面向海外用户的工具站短信成本高不说有些国家的号段还会因为通道质量收不到验证码。邮件就稳定得多只要能接受延迟基本都能收到。再加上现在很多产品要求绑定邮箱所以邮件功能其实比想象中更常用。短信的优点是实时性高、用户手机号身份可信缺点是每条都有成本而且国内短信需要签名和模板审核开发阶段很难快速联调。邮件则没有这种模板限制只要内容不违规随便发测试内容成本也低。所以我的建议是国内C端产品优先短信B端工具、出海产品、企业应用优先邮件或者两者并存。uni-id-pages里邮箱验证码通常是可选的如果你确定用不到也不必费劲配置。再说回uni-id-pages本身它支持username密码登录、手机号验证码、邮箱验证码、微信一键登录等好几种方式。默认配置文件里不一定启用了邮箱登录所以“配置email”这件事本质上分两步先把发送通道打通再把登录/找回密码页面里的邮箱入口打开。很多教程只说前面不说后面结果邮件能发出去前端就是找不到入口特别抓狂。2. 动手前先理清邮件发送链路2.1 一条验证码邮件的完整路径配置之前先画一条完整的链路我不用花哨的图用文字描述。用户在前端输入邮箱点击“获取验证码”前端调用uni-id-co云对象的sendEmailCode方法uni-id-co读取配置文件确认这个场景允许发送邮件然后调用uni-cloud-email公共模块把邮件标题、正文、收件人交出去uni-cloud-email再通过SMTP协议连上你填写的邮箱服务商对方接受邮件后投递到用户收件箱。任何一个环节断了验证码就发不出去。这条链路里最常见的断点有三个一是uni-cloud-email没有完成SMTP配置二是uni-id配置里没开邮箱验证码场景三是前端页面压根没有显示“邮箱登录/验证码登录”入口。这三个断点刚好对应后面三个操作步骤所以我才说先理链路再动手效率最高。另外要注意的是邮件发送是异步的很多时候链路已经通了只是投递有延迟。我在本地测试时经常遇到点击发送后等了几十秒才收到的情况一开始以为失败了其实只是慢。所以排查时不要急着改配置先看看云函数日志里有没有返回成功再判断是不是真的失败。2.2 两种常见配置方式我见过两种配置email的方式。第一种是官方推荐在uniCloud控制台的公共模块里配置uni-cloud-email把发件邮箱的SMTP信息填进去然后在uni-id配置文件里开启场景。好处是配置集中在云端团队成员都能看到而且以后就算换发件邮箱也不需要改前端和云函数代码。第二种是自己在云函数里引入nodemailer写一个自定义的发送邮件云函数再手动对接uni-id。好处是灵活可以自己控制发送逻辑例如定制邮件模板、记录发送日志。坏处是uni-id-co里那些内置的发送验证码方法就不会自动走你的自定义函数了除非你改插件源码后期升级容易踩坑。所以我的建议是除非你有特殊需求否则直接用uni-cloud-email。少写代码少出问题。我早期有个项目就是贪图“灵活”自己封了一套邮件服务结果后来uni-id-pages升级底层调用方式变了我不得不跟着改踩了一堆坑。2.3 配置前需要准备的资料先把下面这些材料准备好免得配置的时候手忙脚乱一个能开启SMTP服务的邮箱账号。国内常用QQ邮箱、163邮箱、阿里云企业邮箱国外可以用Gmail、Outlook。个人测试推荐QQ邮箱配置简单申请授权码也方便。SMTP服务器地址和端口。以QQ邮箱为例服务器是smtp.qq.comSSL端口465也支持587。Gmail是smtp.gmail.com端口587。具体以你用的邮箱服务商为准。邮箱授权码。这里提醒一句不是邮箱登录密码而是邮箱服务商为第三方应用生成的授权码。QQ邮箱在设置-账号-POP3/SMTP服务里开启后生成。发件人名称和发件人邮箱地址用于显示在用户收件箱里。一个已经开通的uniCloud服务空间并且项目里已经安装好uni-id-pages插件。这些材料里最容易出问题的就是授权码。我见过不止一个同事把邮箱密码填进去然后一脸懵地问我为什么失败。记住凡是涉及第三方SMTP绝大多数邮箱服务商都要求用授权码或者专用密码这是为了安全不是你操作错误。3. uni-id-pages配置email实操全流程3.1 在uniCloud控制台配置uni-cloud-email首先登录uniCloud web控制台进入你的服务空间在左侧菜单找到“云函数/云对象”再找到“公共模块”。如果列表里有uni-cloud-email直接点进去如果没有可以先在项目中把uni_modules/uni-cloud-email目录引入然后上传公共模块。我用的是HBuilderX创建的项目通常uni-id-pages依赖列表里会带上它只要你在云函数的package.json里看到uni-cloud-email依赖就需要在控制台完成配置。进入uni-cloud-email配置页后主要填写这几项配置项说明示例hostSMTP服务器地址smtp.qq.comportSMTP端口465secure是否使用SSLtrueauth.user发件邮箱账号testqq.comauth.pass邮箱授权码xxxxxxxxfrom显示的发件人信息我的应用 testqq.com 注意端口465一般对应SSL加密587对应STARTTLS。secure字段要和端口匹配填错了就会出现连接失败。我建议直接选465兼容性最好。填完后保存公共模块级的配置会立即生效。如果有多个云函数依赖这个模块只要配置正确都无需再单独配置。我第一次配置时为了测试还特意新建了一个云函数去调用sendEmail后来发现其实uni-id-co已经在用了白费功夫。3.2 修改uni-id配置文件开启邮箱验证码场景公共模块配置好之后还要让uni-id知道“邮箱验证码要用于哪些场景”。这个开关在uni-id-co云对象的配置文件中路径一般是uniCloud/cloudfunctions/uni-id-co/config.json不同版本的uni-id-pages可能略有差异以你本地的文件为准。在配置文件里找到uni-id相关节点确认service.email下已经声明了需要开启的场景。常见场景有register注册、reset-pwd找回密码、bind绑定邮箱每个场景可以设置验证码有效期ttl单位是秒。我习惯把注册和找回密码的有效期设为180秒太短用户来不及输完太长不安全。示例{ uni-id: { service: { email: { senderName: 我的应用, verifyCode: { register: { name: 注册, ttl: 180 }, reset-pwd: { name: 找回密码, ttl: 180 } } } } } }注意不同版本的字段名可能不同有的版本是放在mail节点下有的需要同时配置enabled。改完以后一定要上传或同步这个云对象HBuilderX里右键云对象目录选择“上传部署”。这一步很容易忘我有个同事在本地改了半天下发配置结果线上云函数还是旧逻辑排查了半个多小时才反应过来是没部署。3.3 前端启用邮箱登录和验证码入口后端配置好了前端页面也得把入口露出来不然用户连邮箱验证码的输入框都看不到。uni-id-pages的登录页面通常会在一个配置项里控制登录方式常见位置是uni_modules/uni-id-pages/config.js或pages/uni-id-pages/login/login.vue里的loginTypes数组。你需要确认数组里包含email。例如只保留邮箱和用户名登录可以这样设置export default { loginTypes: [email, username] }设置好之后登录页会自动出现“邮箱登录”或“邮箱验证码登录”的Tab。如果你还希望用户在注册页和找回密码页也能用邮箱验证码同样需要检查对应页面的配置项是否开启了相关场景。很多时候用户反馈前端看不到入口其实不是插件有问题就是这里漏改了。另外有一点值得注意uni-id-pages的页面会根据loginTypes动态渲染但如果你用的版本比较老可能还需要在页面里手动引入邮箱输入框组件。遇到这种情况先看看官方文档里有没有提到uni-forms的邮箱字段别急着改源码。3.4 用moakt临时邮箱跑通首个验证码配置完成后建议先用临时邮箱测一次别拿自己真实邮箱反复刷。这里就要提到moakt这个临时邮箱服务它的域名是moakt.com。打开网站后不需要注册直接会给你生成一个临时邮箱地址类似xxxxmoakt.com。然后把临时邮箱地址填到uni-id-pages的注册页或邮箱验证码登录页点击获取验证码。正常情况下几十秒内moakt的收件箱里会出现一封新邮件。如果没收到先等一两分钟有些邮件服务投递会有延迟也可以看看垃圾箱。moakt这种临时邮箱偶尔会被邮件服务商拦截所以没收到不代表你配置一定有问题可以换一个临时邮箱服务再试。我第一次测试时用的是Gmail结果因为Gmail反过来要求我开启“低安全性应用访问”折腾了半天。后来换成moakt一下就通了。强烈建议你联调阶段也用临时邮箱等确认链路没问题了再换成真实用户场景。4. 常见问题与排查实录4.1 SMTP连接失败/邮箱收不到验证码这是最常遇到的问题十有八九是SMTP配置不对。先看uni-cloud-email的配置host、port、secure三项必须匹配。例如QQ邮箱的465端口对应SSL如果你的secure是false连接会卡在握手阶段日志里会出现socket hang up。再检查授权码。很多人直接填邮箱登录密码这肯定不行。授权码需要到邮箱设置里单独开启并生成。QQ邮箱的路径是设置 - 账号 - POP3/IMAP/SMTP服务 - 开启服务开启后会给一个16位授权码复制粘贴到auth.pass里。最后别忘了看云函数日志。在uniCloud控制台的云函数日志里能看到uni-id-co返回的错误一般会直接告诉你SMTP连接失败还是认证失败。根据错误信息去定位通常几分钟就能解决。还有一种情况比较隐蔽如果你用的是企业邮箱SMTP端口可能被防火墙或企业安全策略封掉。我在帮一个客户排查时最后发现是他们公司网络不允许访问外部465端口换到手机热点一下就通了。公司网络限制这个因素真的很容易被忽略。4.2 验证码校验失败或提示已过期如果邮件能收到但输入验证码后一直提示错误或过期问题多半出在uni-id的配置和前端传参上。首先确认验证码的ttl是不是太短有的场景设了60秒用户从邮箱复制验证码再切回应用已经超时了。建议至少180秒。其次检查前端有没有把邮箱参数正确传给云函数。有时候用户用的是“用户名密码”登录方式再点邮箱验证码时邮箱字段为空自然校验不过。uni-id-pages的页面一般会自动带当前输入的邮箱但如果你改了页面结构字段名可能对不上。还有一个容易忽略的点如果前端和后端不在同一个环境比如本地联调用的是本地云函数但发送邮件走的是云端公共模块会出现验证码明明发出去了校验时却查不到的情况。尽量统一使用云端部署不要本地和云端混用。4.3 配置正确但生产环境发不出去配置看起来没问题本地测试也能收到但用户上线后反馈收不到邮件。这种情况通常不是代码问题而是发件邮箱的声誉和发送频率被限制了。个人的QQ邮箱或163邮箱每天发送封数是有限的。如果产品注册量稍大马上会触发服务商的限流轻则邮件延迟重则直接被当成垃圾邮件处理。所以产品一旦有真实用户量我建议尽早切换到专业邮件发送服务比如阿里云邮件推送、SendCloud这种。它们在uniCloud里同样可以作为SMTP服务配置有些还支持API调用发送量更大退信处理也更完善。另外要给邮件加上固定的发件人名称和签名不要用乱码字符。正文里尽量带上产品名称避免被用户的垃圾邮件过滤器拦截。我见过一个项目发件人名称是一串随机字母结果被不少企业邮箱直接拒收改成产品名之后送达率明显提升。4.4 快速问题速查表下面这表是我踩坑过程中整理出来的速查清单贴在这里方便你对照排查现象可能原因解决方法云函数日志报ECONNECTIONSMTP端口/加密不匹配检查secure是否与端口对应推荐465SSL云函数日志报Invalid login授权码错误确认用的是授权码而不是邮箱密码邮件发出但收件箱没有被垃圾箱拦截检查垃圾箱临时邮箱建议换服务重试验证码一直提示错误TTL太短或前端邮箱字段为空延长ttl到180s检查页面字段绑定生产环境大面积收不到发件账号被限流换专业邮件推送服务前端没有邮箱登录入口loginTypes未配置email在uni-id-pages配置中启用邮箱登录排查顺序我一般建议先看云函数日志再看公共模块配置最后怀疑邮件服务商。大多数问题都出在前两个环节别一上来就换邮件服务浪费时间。5. 进阶把邮件配置做得更顺手5.1 自定义邮件主题和内容模板如果你觉得uni-cloud-email默认的验证码邮件太朴素可以在云函数里自己拼一个邮件正文。uni-cloud-email的sendEmail方法支持传入subject、text、html等字段html字段可以自己写一个漂亮的模板。例如在uni-id-co里发送验证码时如果想给邮件加个产品名和链接可以重写或包装一下发送逻辑把html模板传进去。不过改uni-id-co内部逻辑要谨慎建议单独封装一个云函数在前端调用时走你自己的云函数再在内部调用uni-id的发送验证码方法。这样既保留原有逻辑又能自定义模板。我个人更推荐的方式是把邮件模板放到前端静态资源或数据库里云函数发送时动态读取这样以后改模板不用重新部署云函数运营也能自己调整文案。5.2 为不同场景设置不同发件人有些产品分国内和海外用户或者有多个品牌子应用希望不同场景用不同发件邮箱。uni-id的配置里场景是可以独立配置的理论上可以给每个场景指定不同的发件账号。做法也不复杂在uni-id配置的每个场景节点下增加独立的mail配置覆盖全局SMTP。不过要注意uni-cloud-email的公共模块配置是全局的如果每个场景要不同发件人可能需要改成在云函数里动态调用uniCloud.sendEmail而不是完全依赖公共模块。这种需求算是比较进阶的如果你不是特别需要建议保持简单用同一个发件人就行。5.3 发送记录与监控邮件发送出去了不代表用户一定收到了。为了以后排查方便最好在云函数里记录每次发送的日志包括收件人、场景、发送结果、耗时等。uniCloud的日志系统自带查询功能但那是被动记录主动打结构化日志会更友好。我习惯在自定义云函数里写类似这样的日志格式console.log(sendEmailLog, { to: event.email, scene: event.scene, result: res, time: Date.now() })这样在日志平台里能直接搜到sendEmailLog按用户或场景过滤定位问题非常快。如果邮件服务商支持回调还可以把回执接入数据库做送达率统计。虽然配置email的核心是“能发出去”但上线后维护才是真正考验人的地方。最后再分享一个我自己的小习惯线上环境我会把发件邮箱单独用一个专用账号不和个人邮箱混用。虽然多一步申请授权码的工作但一旦出问题不会影响个人邮箱退信和垃圾邮件也好清理。配置uni-id-pages的email关键不是代码有多难而是理解那条发送链路。只要链路是通的剩下的都是填参数的事。
返回列表