做 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 提交即可。

代码示例

cURL

curl -d '{"to": "zhangsan@example.com", "scene": "邮箱验证", "code": "153146", "minute": "5"}' \
  https://push.spug.cc/mail/Lp3Vc6hQ2xZ

Python(requests)

import requests

def send_email_code(to_email, code, scene='邮箱验证', minute='5'):
    url = 'https://push.spug.cc/mail/Lp3Vc6hQ2xZ'
    body = {
        'to': to_email,
        'scene': scene,
        'code': code,
        'minute': minute,
    }
    resp = requests.post(url, json=body, timeout=5)
    return resp.json()

result = send_email_code('zhangsan@example.com', '153146')
print(result)

验证码的生成和校验仍然在你自己的后端完成(比如生成随机码、存入 Redis 并设置过期时间),接口只负责把邮件发出去。

请求参数说明

参数 类型 必填 说明
to String 收件人邮箱,多个用英文逗号分隔,最多 10 个
scene String 操作场景,如"邮箱验证"“找回密码”“登录验证”
code String 验证码,4-6 位数字或字母
minute String 验证码有效分钟数

默认模板正文:

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

返回结果说明

请求成功返回:

{
  "code": 200,
  "msg": "请求成功",
  "request_id": "dwezjVRDoe5jgLkR"
}
字段 说明
code 状态码,200 表示请求入库成功(注意:不代表邮件已送达,邮件为异步发送)
msg 返回信息,如"请求成功""请求参数错误"等
request_id 请求 ID,用于后续查询该封邮件的发送状态

常见问题

Q:返回 200 了,但用户说没收到验证码?

code=200 只表示请求被接收并入库,邮件是异步发送的,200 不等于送达。先用返回的 request_id 到推送日志里查这封邮件的真实状态。实际情况中,多数"没收到"是邮件进了收件人的垃圾箱,可以让用户检查一下垃圾邮件目录。

Q:模板编码可以放在前端吗?

不可以。模板编码等于调用凭证,放在前端代码或公开仓库里,别人就能用你的额度发邮件。务必放在后端服务调用。如果服务端 IP 固定,建议再配置 IP 白名单。怀疑编码泄露时,在平台重置编码,旧编码会立即失效。

Q:能自定义邮件内容吗?

可以。默认验证码模板带 scenecodeminute 三个变量;如果你新建了自定义模板,按模板详情里列出的变量传参即可。

Q:一次能发给多个收件人吗?

可以,to 字段多个邮箱用英文逗号分隔,单次最多 10 个。

小结

发邮件验证码不一定要自建 SMTP,用一个 HTTP 接口就能把发送这部分解决掉,后端只需要保留验证码的生成与校验。接入只有两步:拿模板编码、POST 请求,cURL 和 Python 都很简单。需要注意的是返回 200 只是入库成功、邮件异步发送,以及模板编码要放在后端。

本文用到的是 Spug 邮件推送,官网 sms.spug.cc,微信扫码即可获取模板编码。

更多推荐