From abf41f3c95522a60a2ad9b11434e7ed0e06f0413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=A6=E7=A7=8B=E6=97=AD?= Date: Fri, 24 Feb 2023 11:21:36 +0800 Subject: [PATCH] =?UTF-8?q?=E9=AA=8C=E8=AF=81=E9=82=AE=E7=AE=B1=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/email/dto/email.dto.ts | 5 +++++ src/email/email-verify.decorator.ts | 18 ++++-------------- src/email/email.controller.ts | 14 ++++++++++---- src/email/email.service.ts | 13 ++++++++++++- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/email/dto/email.dto.ts b/src/email/dto/email.dto.ts index 95c3ff8..21f9c4b 100644 --- a/src/email/dto/email.dto.ts +++ b/src/email/dto/email.dto.ts @@ -31,3 +31,8 @@ export class EmailVerifyDto { @IsNotEmpty() verifyCode: string } + +export class EmailVerifycationDto extends EmailVerifyDto { + @IsNotEmpty() + scene: EmailScene +} diff --git a/src/email/email-verify.decorator.ts b/src/email/email-verify.decorator.ts index 9b50d1d..bd3ae36 100644 --- a/src/email/email-verify.decorator.ts +++ b/src/email/email-verify.decorator.ts @@ -6,11 +6,9 @@ import { applyDecorators, UseGuards, SetMetadata, - ForbiddenException, } from '@nestjs/common' -import { EmailScene, EmailSendDto } from './dto/email.dto' +import { EmailScene, EmailVerifyDto } from './dto/email.dto' import { EmailService } from './email.service' -import { JwtService } from '@nestjs/jwt' import { type Request } from 'express' const EMAIL_SCENE_KEY = 'EMAIL_SCENE' @@ -20,24 +18,16 @@ class EmailVeriyGuard implements CanActivate { constructor( private emailService: EmailService, private reflector: Reflector, - private jwtService: JwtService, ) {} - canActivate(ctx: ExecutionContext) { + async canActivate(ctx: ExecutionContext) { const scene = this.reflector.get( EMAIL_SCENE_KEY, ctx.getHandler(), ) - const request = ctx.switchToHttp().getRequest() - const { token, email, verifyCode } = request.body - - const payload = this.jwtService.verify(token, { - secret: this.emailService.getEmailJwtSecret(verifyCode, scene), - }) - if (payload.email !== email || payload.scene !== scene) { - throw new ForbiddenException('请输入正确的邮箱验证码') - } + const body: EmailVerifyDto = ctx.switchToHttp().getRequest().body + await this.emailService.verifyEmailCode({ scene, ...body }) return true } } diff --git a/src/email/email.controller.ts b/src/email/email.controller.ts index eab53b5..c627189 100644 --- a/src/email/email.controller.ts +++ b/src/email/email.controller.ts @@ -1,7 +1,7 @@ -import { Body, Controller, Post } from '@nestjs/common' +import { Body, Controller, Post, Get, Query } from '@nestjs/common' import { EmailService } from './email.service' import { ApiTags, ApiOperation } from '@nestjs/swagger' -import { EmailSendDto } from './dto/email.dto' +import { EmailSendDto, EmailVerifycationDto } from './dto/email.dto' @ApiTags('Email') @Controller('api/email') @@ -9,8 +9,14 @@ export class EmailController { constructor(private readonly emailService: EmailService) {} @ApiOperation({ summary: '发送邮箱验证码' }) - @Post('verifyCode') - async sendEmailCode(@Body() payload: EmailSendDto) { + @Get('verifyCode') + async sendEmailCode(@Query() payload: EmailSendDto) { return this.emailService.sendEmailToken(payload.email, payload.scene) } + + @ApiOperation({ summary: '验证邮箱验证码' }) + @Post('verifyCode') + async verifyEmailCode(@Body() payload: EmailVerifycationDto) { + return this.emailService.verifyEmailCode(payload) + } } diff --git a/src/email/email.service.ts b/src/email/email.service.ts index 2f74a22..a4a8b48 100644 --- a/src/email/email.service.ts +++ b/src/email/email.service.ts @@ -3,12 +3,13 @@ import { Injectable, ConflictException, NotFoundException, + ForbiddenException, } from '@nestjs/common' import { securityConfig, SecurityConfig } from 'src/common/configs' import { MailerService } from '@nestjs-modules/mailer' import { JwtService } from '@nestjs/jwt' import { PrismaService } from 'nestjs-prisma' -import { EmailScene } from './dto/email.dto' +import { EmailScene, EmailVerifycationDto, EmailSendDto } from './dto/email.dto' import { UserEntity } from 'src/users/entities/user.entity' @Injectable() @@ -59,6 +60,16 @@ export class EmailService { return { token, userId: user?.id } } + async verifyEmailCode(data: EmailVerifycationDto) { + const { token, verifyCode, email, scene } = data + const payload = this.jwtService.verify(token, { + secret: this.getEmailJwtSecret(verifyCode, scene), + }) + if (payload.email !== email || payload.scene !== scene) { + throw new ForbiddenException('邮箱验证码验证失败') + } + } + getEmailJwtSecret(verifyCode: string, scene: EmailScene) { return this.secureConfig.jwt_access_secret + verifyCode + scene }