首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >邮件验证码接入实践:用 HTTP 接口替代自建 SMTP

邮件验证码接入实践:用 HTTP 接口替代自建 SMTP

原创
作者头像
外滩首席运维
发布2026-07-08 10:27:45
发布2026-07-08 10:27:45
80
举报

记录一下最近给项目接入邮件验证码的做法。需求很常见——注册、登录验证、邮箱绑定都要发验证码邮件——但这次没自建 SMTP,而是直接用 HTTP 接口发,整体比想象中简单。这里把过程和踩到的点整理出来,方便复现。

要解决的问题

发验证码邮件,麻烦的从来不是"发"这个动作,而是配套的一堆事:

  • 邮箱服务和 SMTP 的申请、配置
  • SPF / DKIM / DMARC 解析,配不好邮件进垃圾箱
  • 发送失败的重试、限流处理
  • 发送量大了之后的通道稳定性

这些都属于基础设施,跟业务逻辑没关系。所以这次目标很明确:把发送这一段交出去,后端只保留"生成验证码 + 校验验证码"的逻辑。

接入做法

用的是 Spug 邮件推送,过程分两步。

拿模板编码。 微信扫码登录后进「邮件模板」,默认有一个验证码模板,复制它的模板编码,形如 Cx4Bz9kF2tH。编码本身就是调用凭证,不需要额外申请 token 或做签名。

发送请求。 把编码作为接口路径的最后一段,POST 收件人和模板变量:

代码语言:bash
复制
curl -d '{"to": "dev@example.com", "scene": "邮箱绑定", "code": "271664", "minute": "10"}' \
  https://push.spug.cc/mail/Cx4Bz9kF2tH

后端集成时包一层就行,以 Python 为例:

代码语言:python
复制
import requests

def send_verify_mail(email, code, scene='邮箱绑定', minute='10'):
    body = {'to': email, 'scene': scene, 'code': code, 'minute': minute}
    r = requests.post('https://push.spug.cc/mail/Cx4Bz9kF2tH', json=body, timeout=5)
    data = r.json()
    return data.get('request_id')   # 记下来用于查状态

参数就四个:to(必填,多个收件人用逗号分隔,最多 10 个)、scenecodeminute。默认模板正文:

代码语言:txt
复制
您正在进行${scene},本次验证码为:${code}
请在 ${minute} 分钟内输入验证码完成验证。

怎么确认发送状态

请求成功的返回:

代码语言:json
复制
{"code": 200, "msg": "请求成功", "request_id": "dwezjVRDoe5jgLkR"}

这里有个要注意的地方:code 等于 200 表示请求入库成功,并不等于邮件已送达,因为邮件是异步发送的。所以把 request_id 记到日志里很有必要——后续要查某封邮件到底发没发到,靠的就是它。我的做法是把 request_id 和收件人、时间一起落库,用户来问的时候直接查。

踩坑记录

  • 模板编码不能进前端。 它是凭证,暴露在前端或公开仓库,别人就能用你的额度发信。一律服务端调用。
  • 服务端 IP 固定就配白名单。 在平台开 IP 白名单后,只有白名单内的 IP 能调,多一层保险。
  • 请求要设超时。 发信是外部网络调用,超时和异常都得处理好,别让它拖住注册/登录主流程。
  • 200 不要直接当"已送达"。 前面说过,这是最容易误判的一点。

整体接下来,发信这块基本不用再操心了,后端代码也清爽。用的是 Spug 邮件推送,sms.spug.cc 扫码就能拿到模板编码,想复现的可以去看看。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 要解决的问题
  • 接入做法
  • 怎么确认发送状态
  • 踩坑记录
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档