NestJS 集成 Nodemailer 实现邮件发送与验证码功能详解

作者:墨池时间:2026-10-31 06:40:45浏览:381

本文详细介绍如何在 NestJS 项目中集成 Nodemailer 库实现邮件发送功能。以 QQ 邮箱为例,讲解开启 SMTP 服务、获取授权码及配置传输器的具体步骤。通过封装 EmailService 并提供 sendMail 接口,结合 Redis 存储验证码,完整演示了从后端生成验证码、发送邮件到前端验证的全流程逻辑。

前置准备

首先,我们需要开通目标邮箱的服务。本文以 QQ 邮箱为例进行演示。

前置准备

前置准备

假设服务已开通,首次开启时会生成一个 密钥,请务必妥善记录,后续配置将用到。开通流程较为简单,通常只需填写用途说明,按提示操作即可。

服务开通后,在 NestJS 项目中创建对应的邮箱服务模块。

我们需要引入 nodemailer 这一成熟生态的包,它封装了底层协议细节,开发者可直接调用其 API。

按照惯例,对于独立功能模块如邮箱服务或 Prisma 查询构造器等,建议将其放置在 services 目录下。其他业务模块需使用时,通过依赖注入方式引入即可。

接下来进入具体的代码实现环节。

前置准备

以下是 Nodemailer 包所需的核心配置项,下面逐一解释其含义。

  • host 代表服务器地址,QQ 邮箱对应的是 smtp.qq.com;其他邮箱服务商(如网易)的地址可通过搜索引擎查询获取。
  • port 代表服务器端口号,QQ 邮箱通常为 465,常见安全端口一般为 465。
  • secure 用于标识是否启用安全连接。
  • auth 包含账户认证信息,其中 user 字段填写开通服务的邮箱账号,pass 字段填写前文生成的密钥。
import { Injectable } from '@nestjs/common';
import * as nodemailer from 'nodemailer';
interface MailInfo {
    // 接收方邮箱
    to: string;
    // 标题
    subject: string;
    // 文本
    text?: string;
    // 富文本,如果文本和富文本同时设置,富文本生效。
    html?: string;
  }
@Injectable()
export class EmailService {
  private transporter: nodemailer.Transporter;
  private mailConfig =  {
    host: 'smtp.qq.com',
    port: 465,
    secure: true,
    auth: {
    user: '你开通的邮箱账号',
    pass: '生成的密钥'
  }
  }
  constructor() {
    this.transporter = nodemailer.createTransport(this.mailConfig);
  }
  async sendEmail(mailInfo: MailInfo) {
     const info = await this.transporter.sendMail({
        from: this.mailConfig.auth.user, //发送方邮箱
        ...mailInfo
     })
     return info
  }
}

对于 mailConfig 的配置,建议抽离为独立模块,可通过命名空间管理,并利用 configService 进行读取。为简化演示,此处直接硬编码处理。

上述代码完成了基础配置,核心目的是利用其 sendMail 方法实现邮件发送。所需参数已在代码中明确标注。下面通过邮箱验证码场景进行实战演练。

实战演练

在用户注册或开通账号时,通常需要邮箱验证码校验。逻辑如下:前端点击发送验证码后,将邮箱地址传至后端;后端生成随机验证码并存入 Redis,设置过期时间;随后通过邮箱服务将验证码发送至该邮箱;用户收到邮件后,在表单中输入验证码并提交,后端再与 Redis 中的值进行比对。

前端代码此处省略,主要涉及点击发送后的倒计时交互,重点展示后端实现。

 @Post('/send/emailCaptcha')
  async sendEmailCaptcha(@Body() emailInfo: {email: string}){
      if(!emailInfo) {
         throw new HttpException('邮箱不能为空', HttpStatus.BAD_REQUEST)
      }
      //生成随机四位数
      const emailCaptcha = Math.floor(Math.random() * 9000) + 1000
      //生成的数据存在redis中,后面添加用户做验证
      await this.redisClient
      .multi()
      .set(
        `emailCaptcha:${emailInfo.email}`,
         emailCaptcha,
      )
      .expire( `emailCaptcha:${emailInfo.email}`, 60 * 30) //30min
      .exec()
      this.emailService.sendEmail({
            to: emailInfo.email,
            html: `<div>
            您本次的验证码是<span style="color:#FFB6C1; font-weight:700; font-size:24px">${emailCaptcha}</span>, 验证码有效期是30分钟 </div>`,
            subject: 'xxx平台邮箱检验提醒'
      })
  }

当前端点击发送并调用该接口后,即可在指定邮箱中收到验证码邮件。

前置准备

最终效果大致如此,具体样式可根据需求调整,核心逻辑已在此处展示,后续业务逻辑较为简单,不再赘述。

写在最后

希望这个简单的邮件服务示例能帮助大家掌握相关技术知识。

到此,关于使用 NestJS 实现邮件发送的代码详解介绍完毕。如需了解更多相关内容,请搜索本站往期文章或继续浏览后续文章,感谢支持!

作者最新文章