4-egg-TS-通用后端管理注册系统-邮箱验证码

该博客介绍了如何使用Nodemailer在Node.js应用中配置并发送邮箱验证码。首先通过npm安装Nodemailer,然后配置QQ邮箱作为发送者。接着在`emailCode.ts`文件中创建发送邮件的方法,包括创建Transporter实例、生成验证码、创建邮件内容和异步发送邮件。此外,还提供了验证邮箱验证码的函数。最后,展示了如何在路由中调用这些功能来发送和验证邮箱验证码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.下载Nodemailer

npm install nodemailer

2.配置邮箱发送者
config.local.ts开发阶段
相关属性获取可见QQ邮箱配置

 // 邮箱相关的配置
  config.smtp = {
    host: 'smtp.qq.com',
    port: 465, // true for 465, false for other ports
    user: '1361533456@qq.com', // 发送者的邮箱
    pass: 'ajusgysoisjlpo77', // 邮箱对应的授权码
  };

3.在app/util目录下新建emailCode.ts

// eslint-disable-next-line @typescript-eslint/no-var-requires
const nodemailer = require('nodemailer');
let transporter;
export default {
  // 创建发送者对象
  createTransporterInstance(ctx) {
    if (transporter) {
      return transporter;
    }
    // 已经将相关配置写在config目录下了,比较安全
    transporter = transporter = nodemailer.createTransport({
      host: ctx.app.config.smtp.host,
      port: ctx.app.config.smtp.port,
      secure: true, // true for 465, false for other ports
      auth: {
        user: ctx.app.config.smtp.user, // 发送者的邮箱
        pass: ctx.app.config.smtp.pass, // 邮箱对应的授权码
      },
    });
  },

  // 创建发送内容
  createEmailInfo(ctx, receiver:string) {
    // 1.生成验证码
    const code = Math.random().toString().slice(2, 6)
      .toUpperCase();
    // 2.生成发送的内容
    const info = {
      from: '1361533033@qq.com', // 发送者
      to: receiver, // 接受者
      subject: '小灰灰管理后台注册验证码', // 邮件标题
      text: `你正在注册小灰灰管理后台系统,你的验证码是:${code}`, // 邮件内容
    };
    // 3.保存验证码
    ctx.session.email = {
      code,
      expire: Date.now() + 60 * 1000, // 一分钟后过期
    };
    return info;
  },

  // 异步:async 发送邮箱
  async sendEmailCode(ctx, receiver:string) {
    const transporter = this.createTransporterInstance(ctx);
    const info = this.createEmailInfo(ctx, receiver);
    return new Promise((resolve, reject) => {
      transporter.sendMail(info, (err, data) => {
        if (err) {
          reject(err);
        } else {
          resolve(data);
        }
      });
    });
  },


  verifyEmailCode(ctx, clientCode) {
    // 1.取出服务端中保存的验证码和过期时间
    const serverCaptcha = ctx.session.email;
    console.log(serverCaptcha);
    let serverCode;
    let serverExpire;
    try {
      serverCode = serverCaptcha.code;
      serverExpire = serverCaptcha.expire;
    } catch (e) {
      // 验证码无论验证成功还是失败,都只能使用一次 提高安全性
      ctx.session.email = null;
      throw new Error('请重新获取验证码1');
    }


    // 2.获得客户端传递过来的验证码
    if (Date.now() > serverExpire) {
      // 验证码无论验证成功还是失败,都只能使用一次 提高安全性
      ctx.session.email = null;
      throw new Error('验证码已经过期');
    } else if (serverCode !== clientCode) {
      // 验证码无论验证成功还是失败,都只能使用一次 提高安全性
      ctx.session.email = null;
      throw new Error('验证码不正确');
    }
    // 验证码无论验证成功还是失败,都只能使用一次 提高安全性
    ctx.session.email = null;
  },
};

4.extend/helper.ts

import EmailCode from '../util/emailCode';
module.exports = {
  // 异步发送邮箱
  async sendEmailCode(receiver:string) {
    return await EmailCode.sendEmailCode(this.ctx, receiver);
  },
  // 验证邮箱验证码
  verifyEmailCode(clientCode) {
    EmailCode.verifyEmailCode(this.ctx, clientCode);
  },
};

5.添加发送邮件路由
app/router.ts

router.get('/emailcode', controller.util.emailCode);

6.发送邮箱验证码
app/controller/util.ts

  public async emailCode() {
    const { ctx } = this;
    try {
      const { email } = ctx.query;
      const data = await ctx.helper.sendEmailCode(email);
      ctx.success(data);
    } catch (e:any) {
      ctx.error(400, e.message);
    }
  }

7.验证邮箱验证码
app/controller/user.ts

 case RegisterTypeEnum.Email:
        // 校验邮箱数据的格式是否正确
        ctx.validate(EmailUserRule, data);
        // 校验邮箱验证码是否正确
        ctx.helper.verifyEmailCode(data.captcha);
        break;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值