diff --git a/apps/backend/src/auth/auth.controller.ts b/apps/backend/src/auth/auth.controller.ts index ff37b413..47f2b491 100644 --- a/apps/backend/src/auth/auth.controller.ts +++ b/apps/backend/src/auth/auth.controller.ts @@ -84,9 +84,11 @@ export class AuthController { @ApiOperation({ summary: '사용자가 로그아웃합니다.' }) @Post('logout') @UseGuards(JwtAuthGuard) // JWT 인증 검사 - logout(@Res() res: Response) { + logout(@Req() req, @Res() res: Response) { // 쿠키 삭제 (옵션이 일치해야 삭제됨) this.tokenService.clearCookies(res); + // 현재 자동로그인에 사용되는 refresh Token db에서 삭제 + this.tokenService.deleteRefreshToken(req.user.sub); return res.status(200).json({ message: AuthResponseMessage.AUTH_LOGGED_OUT, }); diff --git a/apps/backend/src/auth/token/token.service.ts b/apps/backend/src/auth/token/token.service.ts index 7ece2a31..12f681f3 100644 --- a/apps/backend/src/auth/token/token.service.ts +++ b/apps/backend/src/auth/token/token.service.ts @@ -26,6 +26,7 @@ export class TokenService { } async generateRefreshToken(userId: number): Promise { + // 보안성을 높이기 위해 랜덤한 tokenId인 jti를 생성한다 const payload = { sub: userId, jti: uuidv4() }; const refreshToken = this.jwtService.sign(payload, { expiresIn: FIVE_MONTHS, @@ -52,7 +53,7 @@ export class TokenService { } async refreshAccessToken(refreshToken: string): Promise { - // refreshToken 1차 검증한다 + // refreshToken 1차 검증 const decoded = this.jwtService.verify(refreshToken, { secret: process.env.JWT_SECRET, }); @@ -60,6 +61,7 @@ export class TokenService { // 검증된 토큰에서 사용자 ID 추출 const userId = decoded.sub; + // refreshToken 2차 검증 // DB에 저장된 refreshToken과 비교 const isValid = await this.compareStoredRefreshToken(userId, refreshToken); if (!isValid) { @@ -132,4 +134,18 @@ export class TokenService { user.refreshToken = refreshToken; await this.userRepository.save(user); } + + async deleteRefreshToken(id: number) { + // 유저를 찾는다. + const user = await this.userRepository.findOneBy({ id }); + + // 유저가 없으면 오류 + if (!user) { + throw new UserNotFoundException(); + } + + // 유저의 현재 REFRESH TOKEN 삭제 + user.refreshToken = null; + await this.userRepository.save(user); + } }