일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 공룡게임
- typeORM
- Express
- Python
- nodejs
- mongoose
- GIT
- Dinosaur
- 게임
- dfs
- Queue
- 정렬
- jest
- Sequelize
- OCR
- MongoDB
- JavaScript
- Nest.js
- 자료구조
- flask
- class
- cookie
- game
- nestjs
- MySQL
- react
- TypeScript
- Bull
- AWS
- Today
- Total
포시코딩
[Nest.js] 이메일 인증 시스템 (2). cache-manager 본문
개요
이전 글에서 전달받은 이메일에 대해 생성한 인증 번호를 따로 저장하는 코드는 생략했었는데
이번 포스팅을 통해 구현해보고자 한다.
저장할 공간은 cache-manager를 활용할 것이다.
자세한 사용 방법은 아래 글 참고
코드
app.module.ts
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
TypeOrmModule.forRootAsync({ useClass: TypeOrmConfigService }),
CacheModule.register({
ttl: 300000, // 데이터 캐싱 시간(밀리 초 단위)
max: 100, // 최대 캐싱 개수
isGlobal: true,
}),
UsersModule,
],
controllers: [AppController],
providers: [AppService],
})
CacheModule.register() 부분만 참고하면 된다.
ttl (Time-To-Live)은 밀리 초 단위라 1000이 1초인데 테스트라 일단
인증 시간은 5분 정도로 설정했다.
users.service.ts
import _ from 'lodash';
import { CACHE_MANAGER, Inject, Injectable, NotFoundException, UnauthorizedException } from '@nestjs/common';
import { Cache } from 'cache-manager';
import { EmailService } from './email.service';
@Injectable()
export class UsersService {
constructor(
private readonly emailService: EmailService,
@Inject(CACHE_MANAGER) private readonly cacheManager: Cache // cache-manager를 inject 해준다.
) {}
async sendVerification(email: string) {
const verifyToken = this.generateRandomNumber();
await this.cacheManager.set(email, verifyToken); // cache-manager를 통해 저장
await this.sendVerifyToken(email, verifyToken);
}
async sendVerifyToken(email: string, verifyToken: number) {
await this.emailService.sendVerifyToken(email, verifyToken);
}
async verifyEmail(email:string, verifyToken: number) {
const cache_verifyToken = await this.cacheManager.get(email); // cache-manager를 통해 확인
if (_.isNil(cache_verifyToken)) {
throw new NotFoundException('해당 메일로 전송된 인증번호가 없습니다.');
} else if (cache_verifyToken !== verifyToken) {
throw new UnauthorizedException('인증번호가 일치하지 않습니다.');
} else {
await this.cacheManager.del(email); // 인증이 완료되면 del을 통해 삭제
}
}
private generateRandomNumber(): number {
var minm = 100000;
var maxm = 999999;
return Math.floor(Math.random() * (maxm - minm + 1)) + minm;
}
}
추가된 부분은 주석을 통해 확인할 수 있다.
먼저 생성자에서 cache-manager를 inject 해주었으며
sendVerification() 메서드에서 생성된 인증 번호와 이메일을 저장하는 모습을 볼 수 있다.
이후 verifyEmail() 메서드에서
전달받은 email과 token에 대해 검증 과정을 거치는데
해당하는 이메일이 key인 값이 없거나 가져왔는데 인증번호가 다를 경우 throw new Exception을 통해
각각 4xx status code를 반환하게 된다.
만약 두 과정 모두 통과된다면 del을 통해 해당 email에 대한 정보를 삭제해준 뒤에
200 status code를 반환해 인증을 완료시킨다.
테스트
직접 Insomnia를 통해 테스트 해보자
내 이메일로 인증번호를 요청한다.
메일로 인증번호 오는거 확인 (cchoseonghun2 가 서버에 세팅한 관리자 이메일이다.)
예외상황 1. 잘못된 이메일로 인증 요청할 경우
예외상황 2. 잘못된 인증번호로 요청할 경우
올바른 이메일로 전달받은 인증번호를 입력했을 때 200 status code를 받는 것을 볼 수 있다.
정리
추후에 cache-manager는 서버에 부담이 되기 때문에 Redis로 변경할 생각이며
Insomnia 대신 React를 통해 요청해서 실제 사용자로서의 화면을 구현해볼 생각이다.
'Node.js' 카테고리의 다른 글
[Nest.js][CORS] GET 요청에서 cookie를 전달받지 못하는 문제 (0) | 2023.03.02 |
---|---|
[Nest.js] 이메일 인증 시스템 (3). Redis 적용 (1) | 2023.02.24 |
[Nest.js] 이메일 인증 시스템 (1). nodemailer (0) | 2023.02.23 |
[Nest.js] 원하는 시점에 AWS S3에 파일 저장 (0) | 2023.02.23 |
[Nest.js] 캐싱 사용해보기 (0) | 2023.02.22 |