如何在Node最新版本的AWS Lambda中实现SES邮件发送及Recaptcha验证
问题1:使用Node.js最新版本及AWS SDK v3在AWS Lambda中发送AWS SES邮件
前提条件
- Lambda运行时选择Node.js 20.x(该版本已内置AWS SDK v3,无需额外安装依赖)
- 为Lambda执行角色添加SES发送权限,可附加
AmazonSESFullAccess策略(或更细粒度的ses:SendEmail/ses:SendRawEmail权限) - 确保SES已验证发件邮箱/域名,且账户处于移出沙箱状态(否则只能发送到已验证邮箱)
代码示例
import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses"; // 初始化SES客户端(Lambda环境下自动使用执行角色权限,无需手动配置凭证) const sesClient = new SESClient({ region: "us-east-1" }); // 替换为你的AWS区域 export const handler = async (event) => { // 构造邮件参数 const sendEmailParams = { Source: "verified-sender@example.com", // 替换为已验证的发件邮箱 Destination: { ToAddresses: ["recipient@example.com"], // 替换为收件邮箱 }, Message: { Subject: { Data: "测试邮件标题", Charset: "UTF-8", }, Body: { Text: { Data: "这是通过Lambda + SES v3发送的测试邮件内容", Charset: "UTF-8", }, Html: { Data: "<h1>测试邮件</h1><p>这是HTML格式的邮件内容</p>", Charset: "UTF-8", }, }, }, }; try { const command = new SendEmailCommand(sendEmailParams); const response = await sesClient.send(command); return { statusCode: 200, body: JSON.stringify({ message: "邮件发送成功", messageId: response.MessageId }), }; } catch (error) { console.error("邮件发送失败:", error); return { statusCode: 500, body: JSON.stringify({ message: "邮件发送失败", error: error.message }), }; } };
问题2:Node.js 20版本AWS Lambda中验证Google Recaptcha并发送SES邮件
核心要点
- Node.js 20支持原生fetch API,无需安装第三方HTTP库(避免打包ZIP层)
- 将Google Recaptcha秘钥存储在Lambda环境变量中(避免硬编码)
- 验证通过后复用问题1中的SES发送逻辑
步骤与代码示例
配置环境变量:在Lambda控制台添加环境变量
RECAPTCHA_SECRET_KEY,值为你的Google Recaptcha秘钥(从Google Recaptcha控制台获取)完整代码
import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses"; const sesClient = new SESClient({ region: "us-east-1" }); const RECAPTCHA_SECRET_KEY = process.env.RECAPTCHA_SECRET_KEY; // 验证Google Recaptcha的函数 const verifyRecaptcha = async (responseToken) => { const verifyUrl = "https://www.google.com/recaptcha/api/siteverify"; const params = new URLSearchParams({ secret: RECAPTCHA_SECRET_KEY, response: responseToken, }); try { const res = await fetch(verifyUrl, { method: "POST", body: params, headers: { "Content-Type": "application/x-www-form-urlencoded" }, }); const data = await res.json(); // 对于Recaptcha v3,可额外检查score(例如score >= 0.5) return data.success && (data.score ? data.score >= 0.5 : true); } catch (error) { console.error("Recaptcha验证失败:", error); return false; } }; // 发送邮件的函数 const sendEmail = async (recipient, content) => { const params = { Source: "verified-sender@example.com", Destination: { ToAddresses: [recipient] }, Message: { Subject: { Data: "表单提交通知", Charset: "UTF-8" }, Body: { Text: { Data: content, Charset: "UTF-8" } }, }, }; const command = new SendEmailCommand(params); return sesClient.send(command); }; export const handler = async (event) => { // 解析前端传入的Recaptcha响应(假设event.body是JSON格式) const { gRecapResp, recipientEmail, formContent } = JSON.parse(event.body); // 先验证Recaptcha const isRecaptchaValid = await verifyRecaptcha(gRecapResp); if (!isRecaptchaValid) { return { statusCode: 400, body: JSON.stringify({ message: "Recaptcha验证失败" }), }; } // 验证成功后发送邮件 try { const emailResponse = await sendEmail(recipientEmail, formContent); return { statusCode: 200, body: JSON.stringify({ message: "邮件发送成功", messageId: emailResponse.MessageId }), }; } catch (error) { console.error("邮件发送失败:", error); return { statusCode: 500, body: JSON.stringify({ message: "邮件发送失败", error: error.message }), }; } };
注意事项
- 若Lambda部署在VPC内,需配置NAT网关以允许访问Google的Recaptcha验证接口
- 确保前端传入的
gRecapResp是有效的Recaptcha响应令牌(来自前端Recaptcha组件的回调) - Recaptcha v2与v3的验证逻辑略有差异,上述代码兼容两者,v3可根据业务需求调整score阈值
内容的提问来源于stack exchange,提问作者jmagunia
相关产品推荐
相关产品推荐

