在Node.js(express 框架)中使用 nodemailer 实现邮箱注册功能

文章目录

一、准备工作

1、安装 nodemailer

yarn add nodemailer

2、打开 QQ(此处使用QQ邮箱) 的 IMAP/SMTP服务

打开用来发送邮箱的QQ的 IMAP/SMTP服务,并获取授权码

需要使用自己的QQ来向注册的用户发送邮件,所以此处需要开启相关服务。此处获取的授权码后续将用于验证。

二、功能实现

1、发送邮件功能封装

可以新建一个 mailQQ.js 文件,封装发送邮件相关功能,便于后续使用。

(1) 设置邮箱配置

js 复制代码
// mailQQ.js
const nodemailer = require('nodemailer');

// 设置邮箱配置
const transporter = nodemailer.createTransport({
    // 不知为何出错
    // host: "smtp.qq.email",
    service: "qq",
    // use SSL
    // secureConnection: true, 
    port: 465,
    secure: true,
    auth: {
        // 用来发送邮件的邮箱账户
        user: "123456789@qq.com",
        // QQ开启 IMAP/SMTP服务后获取的授权码
        pass: "xxx",
    },
});

期间使用 host: "smtp.qq.email" 的写法时功能无法正常使用,而后在网上查找到相关的资料后,使用 service: "qq" 解决了该问题。

参考链接:

(2) 实现发送邮件功能

js 复制代码
// mailQQ.js
function sendMailToMailId(mailId, verifyCode) {
    // 设置收件人信息
    let mailOptions = {
        // 填写发件人 QQ
        from: '"发件人名称" <123456789@qq.com>',
        // 发送至目标邮箱
        to: mailId,
        // 主题
        subject: "邮箱验证",
        // 文本内容
        text: `您正在使用该 ${mailId} 邮箱进行注册,验证码为:${verifyCode}`,
        // html 模板
        // html: '',
        // 附件
        // attachments:[{filename: '',path: ''}]
    }

    return new Promise((resolve, reject) => {
        // 发送邮件
        transporter.sendMail(mailOptions, (error, info) => {
            if (error) {
                reject(error)
            }else {
                resolve(info)
                console.log(info);
            }
        })
    })
}

module.exports = {
    sendMailToMailId
}

sendMailToMailId 方法接收两个参数, mailId 参数为收件人邮箱, verifyCode 参数为随机生成的验证码。

2、生成随机验证码

创建一个 randomCode.js 文件,用于生成随机验证码。

js 复制代码
// randomCode.js
// 通过 codeLength 可指定生成的验证码长度
function randomCode(codeLength) {
    const characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    let result = '';
    for(let i = 0; i < codeLength; i++) {
        const randomIndex = Math.floor(Math.random() * characters.length);
        result += characters[randomIndex];
    }
    return result;
}

module.exports = {
    randomCode
}
3、发送邮箱验证码

此处使用 Node.js(express 框架) ,数据库使用(Mongodb) 实现相关功能。

js 复制代码
var express = require('express');
var router = express.Router();
// 此处省略 mongodb 连接相关代码
const mongoDB = require('../db/conMongoDB');
const mailQQ = require('../utils/mailQQ');
const randomVerifyCode = require('../utils/randomVerifyCode');

// 邮箱验证信息
let mailVerifyCode = {};

// 发送邮箱验证码
router.post('/mailVerifyCode', async function (req, res, next) {
    // 生成 6 位随机验证码
    const verifyCode = randomVerifyCode.randomCode(6);
    // 发送邮箱
    mailQQ.sendMailToMailId(req.body.email, verifyCode).then(() => {
        // 保存验证码信息,用于后续验证
        mailVerifyCode[req.body.email] = verifyCode;
        res.send({ success: true, code: 0, msg: "验证码已发送" });
    }).catch((err) => {
        console.log(err);
        res.send({ success: false, code: 1, msg: "验证码发送失败" });
    });
})

mailVerifyCode 用于记录收件人邮箱及验证码信息。

json 复制代码
{'123456789@qq.com' : '验证码'}
4、注册功能
js 复制代码
// 注册
router.post('/register', async function (req, res, next) {
    // 验证验证码与邮箱是否匹配
    if (!mailVerifyCode[req.body.email] || req.body.verifyCode != mailVerifyCode[req.body.email]) {
        res.send({ success: false, code: 1, msg: "注册失败,验证码错误" });
    } else {
        const usersTable = mongoDB.collection('users');
        // 判断数据库中是否已存在该用户名
        const findResult = await usersTable.findOne({ "email": req.body.email });
        if (!findResult) {
            // 插入数据
            const insertResult = await usersTable.insertOne({
                "email": req.body.email,
                "password": req.body.password,
                "username": req.body.email,
                "headImg": "",
            });
            if (insertResult) {
                res.send({ success: true, code: 0, msg: "注册成功", data: "" });
            }
        } else {
            res.send({ success: false, code: 1, msg: "注册失败,用户名已存在", data: "" });
        }
    }
})

三、邮件接收消息展示

经测试,收件人邮箱可以是 163 邮箱或 QQ 邮箱。

163 邮箱:

QQ 邮箱:

四、参考资料

相关推荐
Patrick_Wilson32 分钟前
Node.js SSR 内存治理:为什么 --max-old-space-size 不等于进程内存
kubernetes·node.js·v8
fred_kang2 小时前
Claude Code 在 Windows 切换 Node.js 版本后命令失效的排查与解决
node.js
xiaofeichaichai11 小时前
Webpack
前端·webpack·node.js
Python私教14 小时前
把开源 Agent 打包成"解压双击即用"的 Windows 便携包:一条命令的完整实现
node.js
没事别瞎琢磨17 小时前
十一、审计与 Run Session——每一步操作都被记录
人工智能·node.js
没事别瞎琢磨17 小时前
十六、AgentSandbox——把所有模块串起来的编排类
人工智能·node.js
没事别瞎琢磨17 小时前
十二、网络代理与白名单规则引擎
人工智能·node.js
没事别瞎琢磨17 小时前
十四、Git Worktree 隔离执行
人工智能·node.js
没事别瞎琢磨18 小时前
十、统一 Runner 入口——能力检测与模式回退
人工智能·node.js
没事别瞎琢磨18 小时前
八、环境隔离——构建安全的子进程环境
人工智能·node.js