邮箱验证

46 阅读1分钟

邮箱验证

安装配置

npm install nodemailer --save

模型

schema.prisma

// 验证码放入数据库,简单处理
model Captcha {
    id        Int      @id @default(autoincrement())
    code      String
    target    String   @unique  // 接收邮箱
    expiresAt DateTime  // 过期时间
    createAt  DateTime @default(now())

    @@map("captcha")
}

env

# email
EMAIL_HOST=smtp.qq.com
EMAIL_PORT=587
EMAIL_USER=邮箱
EMAIL_CODE=授权码

# captcha
# 验证码过期时间
CAPTCHA_EXPIRESAT=5

config

import { ConfigService } from "@nestjs/config"

export const emailConfig = {
  useFactory: (configService: ConfigService) => ({
    host: configService.get("EMAIL_HOST"),
    port: configService.get("EMAIL_PORT"),
    secure: false,
    auth: {
      user: configService.get("EMAIL_USER"),
      pass: configService.get("EMAIL_CODE"),
    }
  })
}

创建模块

@Global()
@Module({
  controllers: [EmailController],
  providers: [EmailService],
  exports:[EmailService]
})
export class EmailModule {}
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { createTransport, Transporter } from 'nodemailer';
import { emailConfig } from 'src/config';

@Injectable()
export class EmailService {

  constructor(private readonly configService: ConfigService) { }

  async sendMail({ to, subject, html }) {
    const econfig=emailConfig.useFactory(this.configService)
    const transporter: Transporter = createTransport(econfig);
    
    await transporter.sendMail({
      from: {
        name: 'coldpants系统',
        address: econfig.auth.user
      },
      to,
      subject,
      html
    }, (error, info) => {})
  }
}

调用

private async captchaFun(email: string) {
    
    const code = Math.random().toString().slice(2, 8);
    // 邮箱
    const configTime = this.configService.get('CAPTCHA_EXPIRESAT')
    await this.emailService.sendMail({
      to: email,
      subject: '注册验证码',
      html: `<p>你的注册验证码是 ${code}${configTime}分钟有效期</p>`
    });

    // 数据库
    const expiresAt = new Date(Date.now() + (configTime || 10) * 60 * 1000)
    await this.prismaService.captcha.upsert({
      where: { target: email },
      create: { target: email, code, expiresAt },
      update: { code, expiresAt }
    })
}

比对验证码

// 比对验证码
const findCaptcha = await this.prismaService.captcha.findUnique({
  where: { target: cud.email }
})


if (findCaptcha?.code !== cud.captcha || dayjs(findCaptcha.expiresAt) < dayjs()) {
  throw new HttpException('验证码错误或已过期', HttpStatus.BAD_REQUEST)
}