通过 Node.js 搭配 Nodemailer 实现邮箱验证码发送

目录

一、整体思路

二、环境准备

三、代码详细步骤

[1. 引入模块并初始化](#1. 引入模块并初始化)

[2. 配置 Nodemailer 邮件服务](#2. 配置 Nodemailer 邮件服务)

[3. 定义发送验证码接口](#3. 定义发送验证码接口)

[4. 定义校验验证码接口](#4. 定义校验验证码接口)

[5. 启动服务器](#5. 启动服务器)

四、补充说明

一、整体思路

  1. 接收邮箱地址请求

    用户在前端填写邮箱,发送到后端接口(如 /send-code)。

  2. 后端生成验证码并缓存

    后端生成随机验证码,存入 Redis 或内存(带过期时间)。

  3. 使用 Nodemailer 发邮件

    配置邮箱服务器,用 Nodemailer 发送邮件,将验证码发到用户邮箱。

  4. 用户提交验证码校验

    后端验证用户提交的验证码是否正确并且未过期。

二、环境准备

首先,需要安装必要的 Node.js 包:

bash 复制代码
npm install express nodemailer redis
  • express:搭建 HTTP 服务器。

  • nodemailer:发送邮件。

  • redis:存验证码,设置过期时间。

三、代码详细步骤

1. 引入模块并初始化

bash 复制代码
const express = require('express');
const nodemailer = require('nodemailer');
const redis = require('redis');
const { promisify } = require('util');

const app = express();
app.use(express.json());

// 连接 Redis
const redisClient = redis.createClient();
const setAsync = promisify(redisClient.set).bind(redisClient);
const getAsync = promisify(redisClient.get).bind(redisClient);

2. 配置 Nodemailer 邮件服务

可以选择 SMTP 邮件服务器,比如:

  • Gmail

  • QQ邮箱

  • 阿里云邮件推送

  • SendGrid

示例(以 QQ 邮箱为例):

bash 复制代码
const transporter = nodemailer.createTransport({
    host: 'smtp.qq.com',
    port: 465,
    secure: true, // true for 465, false for other ports
    auth: {
        user: '你的QQ邮箱@qq.com', // 发送方邮箱
        pass: '授权码'              // 不是密码!是SMTP授权码!
    }
});

注意:QQ邮箱需要开启 SMTP 服务,并拿到一个授权码,不能用普通密码。

3. 定义发送验证码接口

bash 复制代码
app.post('/send-code', async (req, res) => {
    const { email } = req.body;
    if (!email) {
        return res.status(400).send({ error: 'Email is required' });
    }

    // 生成6位随机验证码
    const code = Math.floor(100000 + Math.random() * 900000).toString();

    // 保存到 Redis,设置过期时间5分钟
    await setAsync(`verify:${email}`, code, 'EX', 300);

    // 发送邮件
    const mailOptions = {
        from: '你的QQ邮箱@qq.com',
        to: email,
        subject: '您的验证码',
        text: `您的验证码是 ${code},有效期5分钟,请勿泄露。`
    };

    try {
        await transporter.sendMail(mailOptions);
        res.send({ message: '验证码发送成功' });
    } catch (err) {
        console.error('发送失败', err);
        res.status(500).send({ error: '验证码发送失败' });
    }
});

4. 定义校验验证码接口

bash 复制代码
app.post('/verify-code', async (req, res) => {
    const { email, code } = req.body;
    if (!email || !code) {
        return res.status(400).send({ error: 'Email and code are required' });
    }

    const savedCode = await getAsync(`verify:${email}`);

    if (!savedCode) {
        return res.status(400).send({ error: '验证码已过期或不存在' });
    }

    if (savedCode === code) {
        return res.send({ message: '验证成功' });
    } else {
        return res.status(400).send({ error: '验证码错误' });
    }
});

5. 启动服务器

bash 复制代码
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`服务器运行在 http://localhost:${PORT}`);
});

四、补充说明

  1. 限流控制(防止恶意刷验证码)

    • 比如一个邮箱1分钟内只能发送一次。

    • 可以在 Redis 里加一层锁或者计数器。

  2. 验证码加密

    • 验证码可以使用简单加密(例如哈希存储),提高安全性。
  3. 防止暴力破解

    • 连续错误输验证码次数超过3次,锁定一段时间。
  4. 生产环境发送 HTML 格式邮件

    • 邮件正文可以用 HTML 格式美化,比如加品牌 Logo、验证码提示等。
  5. 异步处理发送邮件

    • 邮件发送可以做成异步,或者通过消息队列(如 RabbitMQ)解耦,提高响应速度。
相关推荐
故事还在继续吗2 小时前
C++20关键特性
开发语言·c++·c++20
青少儿编程课堂3 小时前
2026青少儿信息素养大赛备赛指南!Python/Scratch/C++备考要点
开发语言·c++·python
旖-旎3 小时前
深搜练习(电话号码字母组合)(3)
c++·算法·力扣·深度优先遍历
AIFarmer4 小时前
【无标题】
开发语言·c++·算法
John_ToDebug4 小时前
WebHostView 与 TabStrip 交互机制深度解析
c++·chrome·windows
大貔貅喝啤酒5 小时前
接口测试_Postman(详细版)
javascript·测试工具·node.js·自动化·postman
南境十里·墨染春水5 小时前
C++笔记 STL——set
开发语言·c++·笔记
dgaf5 小时前
DX12 快速教程(17) —— 立体图标与合并渲染
c语言·c++·3d·图形渲染·d3d12
桜吹雪5 小时前
Langchain.js官方文档:构建具备按需加载技能的 SQL 助手
javascript·人工智能·node.js
charlie1145141918 小时前
通用GUI编程技术——图形渲染实战(三十八)——顶点缓冲与输入布局:GPU的第一个三角形
开发语言·c++·学习·图形渲染·win32