1- import { Injectable , OnModuleInit } from '@nestjs/common' ;
1+ import { Inject , Injectable , OnModuleInit } from '@nestjs/common' ;
22import { JwtService } from '@nestjs/jwt' ;
33import * as bcrypt from 'bcrypt' ;
4+ import Redis from 'ioredis' ;
45import { v4 as uuid4 } from 'uuid' ;
56
67import { LoginDto } from './dto/login.dto' ;
@@ -11,48 +12,25 @@ import { UsersRepository } from '@users/users.repository';
1112interface RefreshTokenData {
1213 userId : number ;
1314 nickname : string ;
14- expiredAt : Date ;
1515}
1616
1717@Injectable ( )
18- export class AuthService implements OnModuleInit {
19- private refreshTokens : Record < string , RefreshTokenData > = { } ;
20- private readonly REFRESH_TOKEN_CONFIG = {
21- EXPIRE_INTERVAL : 7 * 24 * 60 * 60 * 1000 , // 7일
22- CLEANUP_INTERVAL : 60 * 60 * 1000 , // 1시간
23- } as const ;
18+ export class AuthService {
19+ private readonly REFRESH_TOKEN_TTL = 7 * 24 * 60 * 60 ;
2420
2521 constructor (
2622 private readonly jwtService : JwtService ,
2723 private readonly usersRepository : UsersRepository ,
24+ @Inject ( 'REDIS_REFRESH_TOKEN' ) private readonly refreshTokensRedisClient : Redis ,
2825 ) { }
2926
30- getInfo ( refreshToken : string ) {
31- const user = this . refreshTokens [ refreshToken ] ;
32- return user ? user . userId : null ;
27+ async getInfo ( refreshToken : string ) {
28+ const refreshTokenData : RefreshTokenData = JSON . parse ( await this . refreshTokensRedisClient . get ( refreshToken ) ) ;
29+ return refreshTokenData ? refreshTokenData . userId : null ;
3330 }
3431
3532 getRefreshTokenExpireTime ( ) {
36- return this . REFRESH_TOKEN_CONFIG . EXPIRE_INTERVAL ;
37- }
38-
39- onModuleInit ( ) {
40- this . startPeriodicCleanup ( ) ;
41- }
42-
43- private startPeriodicCleanup ( ) {
44- setInterval ( ( ) => {
45- this . cleanupExpiredTokens ( ) ;
46- } , this . REFRESH_TOKEN_CONFIG . CLEANUP_INTERVAL ) ;
47- }
48-
49- private cleanupExpiredTokens ( ) {
50- const now = new Date ( ) ;
51- const expiredTokens = Object . keys ( this . refreshTokens ) . filter ( ( token ) => this . refreshTokens [ token ] . expiredAt < now ) ;
52-
53- expiredTokens . forEach ( ( token ) => {
54- this . removeRefreshToken ( token ) ;
55- } ) ;
33+ return this . REFRESH_TOKEN_TTL ;
5634 }
5735
5836 async validateUser ( loginDto : LoginDto ) {
@@ -65,35 +43,32 @@ export class AuthService implements OnModuleInit {
6543 return { userId : user . userId , nickname : user . nickname } ;
6644 }
6745
68- generateRefreshToken ( userId : number , nickname : string ) {
46+ async generateRefreshToken ( userId : number , nickname : string ) {
6947 const token = uuid4 ( ) ;
70- this . refreshTokens [ token ] = {
48+ const tokenData : RefreshTokenData = {
7149 userId,
7250 nickname,
73- expiredAt : new Date ( Date . now ( ) + this . REFRESH_TOKEN_CONFIG . EXPIRE_INTERVAL ) ,
7451 } ;
52+
53+ await this . refreshTokensRedisClient . set ( token , JSON . stringify ( tokenData ) , 'EX' , this . REFRESH_TOKEN_TTL ) ;
7554 return token ;
7655 }
7756
7857 async generateAccessToken ( refreshToken : string ) {
79- await this . validateRefreshToken ( refreshToken ) ;
80- return this . jwtService . sign ( this . refreshTokens [ refreshToken ] , {
58+ const tokenData : RefreshTokenData = await this . validateRefreshToken ( refreshToken ) ;
59+ return this . jwtService . sign ( tokenData , {
8160 expiresIn : '2d' ,
8261 secret : process . env . JWT_ACCESS_SECRET ,
8362 } ) ;
8463 }
8564
8665 private async validateRefreshToken ( refreshToken : string ) {
87- const tokenData = this . refreshTokens [ refreshToken ] ;
66+ const tokenData = await this . refreshTokensRedisClient . get ( refreshToken ) ;
8867 if ( ! tokenData ) throw RefreshTokenException . invalid ( ) ;
89-
90- if ( tokenData . expiredAt < new Date ( ) ) {
91- this . removeRefreshToken ( refreshToken ) ;
92- throw RefreshTokenException . expired ( ) ;
93- }
68+ return JSON . parse ( tokenData ) ;
9469 }
9570
96- removeRefreshToken ( refreshToken : string ) {
97- delete this . refreshTokens [ refreshToken ] ;
71+ async removeRefreshToken ( refreshToken : string ) {
72+ await this . refreshTokensRedisClient . del ( refreshToken ) ;
9873 }
9974}
0 commit comments