做 Web 项目几乎绕不开邮件验证码注册、登录二次验证、找回密码都要发。自己搭 SMTP 成本不低还常遇到邮件进垃圾箱。这篇分享一个更省事的发法——用一个 HTTP 接口发邮件验证码不自建 SMTP附 cURL 和 Python 代码看完就能接。为什么不建议自己搭 SMTP自建邮件发送服务要处理的事情比想象中多申请邮箱服务、配置 SMTP 账号配置 SPF、DKIM、DMARC 解析记录否则邮件大概率被判垃圾邮件自己实现发送、失败重试、并发控制发送量上来后还要应对服务商的限流和封号风险对大多数项目来说发验证码只是个辅助功能没必要为它维护一整套邮件基础设施。用一个验证码邮件 API 来发把这部分交出去更划算。接入步骤下面以 Spug 邮件推送为例说明邮件验证码接口的接入方式。1. 获取模板编码微信扫码登录后进入「邮件模板」页面系统默认提供一个验证码模板复制它的模板编码形如Lp3Vc6hQ2xZ。这个模板编码本身就是调用凭证不需要额外申请 token也不需要做签名这是它接入快的原因之一。2. 拼接接口地址模板编码作为接口 URL 的最后一段POST https://push.spug.cc/mail/{模板编码}3. 发送请求把收件人和模板变量作为 JSON 提交即可。代码示例cURLcurl-d{to: zhangsanexample.com, scene: 邮箱验证, code: 153146, minute: 5}\https://push.spug.cc/mail/Lp3Vc6hQ2xZPythonrequestsimportrequestsdefsend_email_code(to_email,code,scene邮箱验证,minute5):urlhttps://push.spug.cc/mail/Lp3Vc6hQ2xZbody{to:to_email,scene:scene,code:code,minute:minute,}resprequests.post(url,jsonbody,timeout5)returnresp.json()resultsend_email_code(zhangsanexample.com,153146)print(result)验证码的生成和校验仍然在你自己的后端完成比如生成随机码、存入 Redis 并设置过期时间接口只负责把邮件发出去。请求参数说明参数类型必填说明toString是收件人邮箱多个用英文逗号分隔最多 10 个sceneString否操作场景如邮箱验证“找回密码”“登录验证”codeString否验证码4-6 位数字或字母minuteString否验证码有效分钟数默认模板正文您正在进行${scene}本次验证码为${code} 请在 ${minute} 分钟内输入验证码完成验证。返回结果说明请求成功返回{code:200,msg:请求成功,request_id:dwezjVRDoe5jgLkR}字段说明code状态码200 表示请求入库成功注意不代表邮件已送达邮件为异步发送msg返回信息如请求成功请求参数错误等request_id请求 ID用于后续查询该封邮件的发送状态常见问题Q返回 200 了但用户说没收到验证码code200只表示请求被接收并入库邮件是异步发送的200 不等于送达。先用返回的request_id到推送日志里查这封邮件的真实状态。实际情况中多数没收到是邮件进了收件人的垃圾箱可以让用户检查一下垃圾邮件目录。Q模板编码可以放在前端吗不可以。模板编码等于调用凭证放在前端代码或公开仓库里别人就能用你的额度发邮件。务必放在后端服务调用。如果服务端 IP 固定建议再配置 IP 白名单。怀疑编码泄露时在平台重置编码旧编码会立即失效。Q能自定义邮件内容吗可以。默认验证码模板带scene、code、minute三个变量如果你新建了自定义模板按模板详情里列出的变量传参即可。Q一次能发给多个收件人吗可以to字段多个邮箱用英文逗号分隔单次最多 10 个。小结发邮件验证码不一定要自建 SMTP用一个 HTTP 接口就能把发送这部分解决掉后端只需要保留验证码的生成与校验。接入只有两步拿模板编码、POST 请求cURL 和 Python 都很简单。需要注意的是返回 200 只是入库成功、邮件异步发送以及模板编码要放在后端。本文用到的是 Spug 邮件推送官网 sms.spug.cc微信扫码即可获取模板编码。