You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于AWS Lambda+Serverless架构,如何用SNS给新注册用户发验证邮件?

解决新用户邮箱验证邮件发送问题(基于AWS无服务器架构)

首先你碰到的「邮箱地址未验证」错误,根源是AWS SES默认处于沙盒模式——这个模式下所有发件人和收件人邮箱都必须提前在SES控制台验证,主要是AWS用来防范垃圾邮件的机制。下面给你拆解可行的解决方案,以及如何结合Lambda等无服务器服务实现完整流程:

一、先突破SES的核心限制

1. 生产环境:申请移出SES沙盒(推荐)

如果你的项目已经准备进入正式使用,直接在AWS控制台提交移出申请即可:

  • 登录SES控制台,找到「移出沙盒」的入口
  • 填写你的使用场景(比如用户注册验证邮件)、预计发送量、联系方式等信息
  • AWS审核通过后,你就可以给任意未验证的收件人发送邮件了,只要发件人地址是已验证的(比如你的企业域名邮箱)

2. 开发/测试阶段:临时过渡方案

如果还在开发测试阶段,不想等审核,可以:

  • 在SES控制台手动添加几个测试用户的邮箱作为验证收件人,用来跑通流程
  • 或者使用SES的模板功能配合Lambda,不过核心还是要先处理沙盒的限制

二、用Lambda + SES实现验证邮件发送的完整流程

其实不需要SNS(除非你需要额外的消息状态跟踪),直接用Lambda触发SES发送是最简洁的无服务器方案,流程如下:

1. 整体流程步骤

  • 用户提交注册请求到API Gateway(或直接触发注册Lambda)
  • 注册Lambda生成随机验证token,将用户邮箱、token、未验证状态等信息存入DynamoDB
  • 注册Lambda调用SES的sendEmail或sendTemplatedEmail API发送验证邮件
  • 用户点击邮件中的验证链接,触发另一个验证Lambda,更新DynamoDB中用户的验证状态

2. Node.js Lambda代码示例

首先确保Lambda角色拥有SES发送权限(给角色添加AmazonSESFullAccess或更细粒度的权限,比如仅允许ses:SendEmail操作)

const AWS = require('aws-sdk');
const ses = new AWS.SES({ region: '你的AWS区域,比如us-east-1' });
const crypto = require('crypto');

exports.handler = async (event) => {
  // 从注册请求中获取用户邮箱
  const userEmail = event.email;
  // 生成随机验证token
  const verifyToken = crypto.randomBytes(16).toString('hex');
  
  // 1. 将用户信息和验证token存入DynamoDB
  const dynamoDB = new AWS.DynamoDB.DocumentClient();
  await dynamoDB.put({
    TableName: '你的用户表名称',
    Item: {
      email: userEmail,
      verifyToken: verifyToken,
      isVerified: false,
      createdAt: new Date().toISOString()
    }
  }).promise();
  
  // 2. 构造验证邮件内容
  const emailParams = {
    Destination: {
      ToAddresses: [userEmail]
    },
    Message: {
      Body: {
        Html: {
          Charset: 'UTF-8',
          Data: `请点击以下链接验证你的邮箱:<a href="https://你的域名/verify?token=${verifyToken}">立即验证</a>`
        },
        Text: {
          Charset: 'UTF-8',
          Data: `请访问以下链接验证你的邮箱:https://你的域名/verify?token=${verifyToken}`
        }
      },
      Subject: {
        Charset: 'UTF-8',
        Data: '请完成邮箱验证'
      }
    },
    Source: '你的已验证发件人邮箱,比如no-reply@yourdomain.com'
  };
  
  // 3. 调用SES发送邮件
  try {
    await ses.sendEmail(emailParams).promise();
    return { statusCode: 200, body: '验证邮件已发送,请查收邮箱' };
  } catch (error) {
    console.error('发送邮件失败:', error);
    return { statusCode: 500, body: '发送验证邮件失败,请稍后重试' };
  }
};

三、关于AWS SNS的使用场景

SNS主要用于消息通知、订阅推送,其实发送验证邮件用SES就足够了。但如果你的需求涉及以下场景,可以结合SNS:

  • 需要跟踪邮件的发送状态(比如是否成功送达、用户是否打开、是否被拒收)
  • 想把邮件发送任务和注册业务逻辑解耦(比如注册Lambda把发送请求推到SNS主题,另一个Lambda监听主题再调用SES)
  • 需要处理邮件异常状态(比如把SES的 bounce、complaint通知推到SNS,再用Lambda标记无效邮箱)

四、额外注意事项

  • 发件人地址验证:无论是否移出沙盒,发件人邮箱/域名必须在SES控制台验证,建议验证整个域名(比如yourdomain.com),这样该域名下的所有邮箱都可作为发件人
  • 反垃圾邮件规范:邮件内容要符合AWS的规则,避免被标记为垃圾邮件,比如不要用过度营销词汇,确保验证链接有效且指向正规域名
  • Lambda权限最小化:给Lambda角色配置必要的最小权限,比如仅允许读写指定的DynamoDB表、仅允许调用SES发送邮件

内容的提问来源于stack exchange,提问作者Akib Deraiya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:09:29