JS/Nest.js

[Nest] Jwt 토큰 재발급 구현

Mini_96 2024. 9. 18. 21:08

* 의사코드

  • accesstoken을 header > authorization에 함께 보내야함
  • 이를 바탕으로 사용자 구분
  • 쓰다가 만료되면 refresh token으로 access token 재발급
  • refresh token도 만료되면 refresh token 재발급
  • access token으로는 절대 재발급 불가 (예외처리)

 

* 구현

  • 서비스
/**
 * 토큰 검증
 * @param token
 */
 verifyToken(token: string){
  return this.jwtService.verify(token, {
    secret: JWT_SECRET,
  });
 }

/**
 * refresh 토큰 => access 토큰 재발급
 * @param token
 */
rotateToken(token: string, isRefreshToken: boolean){
   const decoded = this.jwtService.verify(token,{
     secret:JWT_SECRET,
   });

  /**
   * sub : id
   * email
   * type : access | refresh
   */
  if(decoded.type !== 'refresh'){
     throw new UnauthorizedException('토큰 재발급은 Refresh 토큰으로만 가능합니다!')
   }

  return this.signToken({
    ...decoded,
  }, isRefreshToken);
 }
  • 컨트롤러
@Post('token/access')
postTokenAccess(
  @Headers('authorization') rawToken: string,){
  const token = this.authService.extractTokenFromHeader(rawToken, true);

  const newToken = this.authService.rotateToken(token,false);

  /**
   * {accessToken : {token}}
   */
  return {
    accessToken: newToken,
  }

}

@Post('token/refresh')
postTokenRefresh(
  @Headers('authorization') rawToken: string,){
  const token = this.authService.extractTokenFromHeader(rawToken, true);

  const newToken = this.authService.rotateToken(token,true);

  /**
   * {refreshToken : {token}}
   */
  return {
    refreshToken: newToken,
  }

}

 

* 테스트

refresh token으로 access token 재발급성공
access token으로 access token 재발급 실패
엑세스 토큰으로 refresh 토큰 재발급 실패
refresh 토큰으로 refresh 토큰 재발급
access 토큰으로 refresh 토큰 재발급 실패