Mailtrap 邮件集成
使用 Mailtrap 的 Email API 和沙箱功能,为应用添加事务性邮件发送的模式,涵盖身份验证、环境隔离和常见投递陷阱。
何时激活
- 实现“发送邮件”功能(注册确认、密码重置、通知、收据)
- 调试开发/预发环境中邮件无法到达的问题
- 为项目设置首次邮件发送集成
- 审查直接调用邮件 API 而未进行沙箱隔离的代码
核心概念
沙箱与生产环境的隔离。 Mailtrap 提供沙箱 API,可捕获邮件而不实际投递,用于开发/预发环境,确保测试邮件不会进入真实收件箱。生产发送则使用独立的已验证域名端点。切勿将开发环境指向生产发送端点。
身份验证。 请求使用 Authorization 头部中的 Bearer 令牌。令牌按项目范围隔离;沙箱和生产环境通常使用不同的令牌。
域名验证。 生产发送要求通过 DNS 记录(SPF、DKIM、DMARC)验证发送域名,之后 Mailtrap 才会向真实收件人投递邮件。跳过此步骤可能导致静默投递失败或邮件进入垃圾邮件文件夹。
代码示例
// 通过 Mailtrap 的 Email API(生产环境)发送邮件
async function sendEmail(to: string, subject: string, html: string) {
const response = await fetch("https://send.api.mailtrap.io/api/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.MAILTRAP_API_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: { email: "[email protected]", name: "你的应用" },
to: [{ email: to }],
subject,
html,
}),
});
if (!response.ok) {
throw new Error(`邮件发送失败:${response.status}`);
}
return response.json();
}
// 同一调用,在非生产环境中路由到沙箱
const MAILTRAP_ENDPOINT = process.env.NODE_ENV === "production"
? "https://send.api.mailtrap.io/api/send"
: `https://sandbox.api.mailtrap.io/api/send/${process.env.MAILTRAP_INBOX_ID}`;
反模式
| 反模式 | 问题原因 | 应采用的方案 |
|---|---|---|
| 在开发/测试环境中使用生产发送端点 | 真实的测试邮件会到达真实收件箱,存在垃圾投诉风险和测试数据泄露风险 | 将非生产环境路由到沙箱端点 |
| 在源码中硬编码 API 令牌 | 一旦提交到版本控制,存在凭证泄露风险 | 从环境变量/密钥管理器加载令牌 |
| 在域名验证完成前发送 | 邮件静默失败或进入垃圾邮件箱 | 在启用生产发送前验证 SPF/DKIM/DMARC 记录 |
| 发送失败时未设置重试/错误处理 | 静默的通知失败(例如,用户从未收到密码重置邮件) | 检查响应状态,记录失败信息,展示可操作错误 |
最佳实践
- 将沙箱和生产令牌保存在不同的环境变量中,切勿跨环境共享一个令牌
- 在所有涉及邮件的生产上线前验证发送域名的 DNS 记录
- 记录投递失败信息,并包含足够的调试上下文(收件人、模板、时间戳、响应码)
- 将邮件发送视为可能失败的网络调用:使用 try/catch 包裹,切勿假设成功
相关技能
api-and-interface-design, security-and-hardening, ci-cd-and-automation