在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 邮箱:

四、参考资料

相关推荐
hxmmm2 小时前
自定义封装 vue多页项目新增项目脚手架
前端·javascript·node.js
濮水大叔2 小时前
VonaJS是如何做到文件级别精确HMR(热更新)的?
typescript·node.js·nestjs
小胖霞5 小时前
全栈系列(15)github Actions自动化部署前端vue
前端·node.js·github
LYFlied5 小时前
【一句话概述】Webpack、Vite、Rollup 核心区别
前端·webpack·node.js·rollup·vite·打包·一句话概述
程序员爱钓鱼10 小时前
Node.js 编程实战:MongoDB 基础与 Mongoose 入门
后端·node.js·trae
程序员爱钓鱼10 小时前
Node.js 编程实战:MySQL PostgreSQL数据库操作详解
后端·node.js·trae
古韵11 小时前
当 API 文档走进编辑器会怎样?
vue.js·react.js·node.js
小胖霞1 天前
企业级全栈项目(14) winston记录所有日志
vue.js·前端框架·node.js
Anita_Sun1 天前
🎨 基础认知篇:打破单线程误区
node.js
Anita_Sun1 天前
😋 核心原理篇:线程池的 5 大核心组件
前端·node.js