diff --git a/src/main/java/com/mpnp/baechelin/exception/GlobalExceptionHandler.java b/src/main/java/com/mpnp/baechelin/exception/GlobalExceptionHandler.java index cd2baa6..8db9459 100644 --- a/src/main/java/com/mpnp/baechelin/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/mpnp/baechelin/exception/GlobalExceptionHandler.java @@ -42,7 +42,7 @@ protected ResponseEntity handleMalformedJwtException(MalformedJwt @ExceptionHandler(value = ExpiredJwtException.class) protected ResponseEntity handleExpiredJwtException(ExpiredJwtException e) { log.error("만료된 JWT 토큰입니다."); - return ErrorResponse.toResponseEntity(ErrorCode.EXPIRED_TOKEN); + return ErrorResponse.toResponseEntity(ErrorCode.EXPIRED_ACCESS_TOKEN); } @ExceptionHandler(value = UnsupportedJwtException.class) diff --git a/src/main/java/com/mpnp/baechelin/login/jwt/exception/RestAuthenticationEntryPoint.java b/src/main/java/com/mpnp/baechelin/login/jwt/exception/RestAuthenticationEntryPoint.java index 8bc4e72..7cfd8d3 100644 --- a/src/main/java/com/mpnp/baechelin/login/jwt/exception/RestAuthenticationEntryPoint.java +++ b/src/main/java/com/mpnp/baechelin/login/jwt/exception/RestAuthenticationEntryPoint.java @@ -9,7 +9,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.time.LocalDate; import java.time.LocalDateTime; // 인증되지 않은 유저가 요청을 했을 때 동작하는 클래스 @@ -35,11 +34,11 @@ else if(exception.equals(ErrorCode.WRONG_TYPE_SIGNATURE.getCode())) { setResponse(response, ErrorCode.WRONG_TYPE_SIGNATURE); } //토큰 만료된 경우 - else if(exception.equals(ErrorCode.EXPIRED_TOKEN.getCode())) { - setResponse(response, ErrorCode.EXPIRED_TOKEN); + else if(exception.equals(ErrorCode.EXPIRED_ACCESS_TOKEN.getCode())) { + setResponse(response, ErrorCode.EXPIRED_ACCESS_TOKEN); } else { - setResponse(response, ErrorCode.TOKEN_NOT_EXIST); + setResponse(response, ErrorCode.INVALID_ACCESS_TOKEN); } } diff --git a/src/main/java/com/mpnp/baechelin/login/jwt/filter/TokenAuthenticationFilter.java b/src/main/java/com/mpnp/baechelin/login/jwt/filter/TokenAuthenticationFilter.java index 577dc79..3383e12 100644 --- a/src/main/java/com/mpnp/baechelin/login/jwt/filter/TokenAuthenticationFilter.java +++ b/src/main/java/com/mpnp/baechelin/login/jwt/filter/TokenAuthenticationFilter.java @@ -3,7 +3,6 @@ import com.mpnp.baechelin.exception.ErrorCode; import com.mpnp.baechelin.login.jwt.AuthToken; import com.mpnp.baechelin.login.jwt.AuthTokenProvider; -import com.mpnp.baechelin.util.HeaderUtil; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.MalformedJwtException; import io.jsonwebtoken.UnsupportedJwtException; @@ -37,9 +36,7 @@ protected void doFilterInternal( FilterChain filterChain) throws ServletException, IOException { // 요청값의 header에서 토큰을 뽑아온다. - String tokenStr = HeaderUtil.getAccessToken(request); - // String으로 된 token을 AuthToken객체로 변환해준다. - AuthToken token = tokenProvider.convertAuthToken(tokenStr); + AuthToken token = tokenProvider.convertAccessToken(request); try { if (token != null && token.tokenValidate()) { @@ -56,13 +53,13 @@ protected void doFilterInternal( request.setAttribute("exception", ErrorCode.WRONG_TYPE_TOKEN.getCode()); } catch (ExpiredJwtException e) { log.info("만료된 JWT 토큰입니다."); - request.setAttribute("exception", ErrorCode.EXPIRED_TOKEN.getCode()); + request.setAttribute("exception", ErrorCode.EXPIRED_ACCESS_TOKEN.getCode()); } catch (UnsupportedJwtException e) { log.info("지원되지 않는 형식이나 구성의 JWT 토큰입니다."); request.setAttribute("exception", ErrorCode.WRONG_TYPE_TOKEN.getCode()); } catch (IllegalArgumentException e) { log.info(e.toString().split(":")[1].trim()); - request.setAttribute("exception", ErrorCode.TOKEN_NOT_EXIST.getCode()); + request.setAttribute("exception", ErrorCode.INVALID_ACCESS_TOKEN.getCode()); } filterChain.doFilter(request, response); diff --git a/src/main/java/com/mpnp/baechelin/login/jwt/service/TokenService.java b/src/main/java/com/mpnp/baechelin/login/jwt/service/TokenService.java index d6f5bf6..642879b 100644 --- a/src/main/java/com/mpnp/baechelin/login/jwt/service/TokenService.java +++ b/src/main/java/com/mpnp/baechelin/login/jwt/service/TokenService.java @@ -3,14 +3,13 @@ import com.mpnp.baechelin.common.properties.AppProperties; import com.mpnp.baechelin.exception.CustomException; import com.mpnp.baechelin.exception.ErrorCode; -import com.mpnp.baechelin.login.oauth.common.AuthResponse; -import com.mpnp.baechelin.login.oauth.entity.RoleType; import com.mpnp.baechelin.login.jwt.AuthToken; import com.mpnp.baechelin.login.jwt.AuthTokenProvider; import com.mpnp.baechelin.login.jwt.entity.UserRefreshToken; import com.mpnp.baechelin.login.jwt.repository.UserRefreshTokenRepository; +import com.mpnp.baechelin.login.oauth.common.AuthResponse; +import com.mpnp.baechelin.login.oauth.entity.RoleType; import com.mpnp.baechelin.util.CookieUtil; -import com.mpnp.baechelin.util.HeaderUtil; import io.jsonwebtoken.Claims; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -37,13 +36,12 @@ public class TokenService { * 새로운 Access Token을 재발급 받는 메소드 * Access Token이 만료되었는 지와 상관없이 재발급 * Access Token을 재발급 받을 때, Refresh Token도 재발급해주어서 보안을 높인다. - * @param request Access Token이 들어있는 + * @param request Access Token이 들어있는 request * @param response 쿠키를 삭제하기 위한 response * @return 재발급된 Access Token */ public AuthResponse refreshToken(HttpServletRequest request, HttpServletResponse response) { - String accessToken = HeaderUtil.getAccessToken(request); - AuthToken authToken = tokenProvider.convertAuthToken(accessToken); + AuthToken authToken = tokenProvider.convertAccessToken(request); Claims claims = authToken.getExpiredTokenClaims(); @@ -59,8 +57,22 @@ public AuthResponse refreshToken(HttpServletRequest request, HttpServletResponse String refreshToken = CookieUtil.getCookie(request, REFRESH_TOKEN) .map(Cookie::getValue) .orElse((null)); - AuthToken authRefreshToken = tokenProvider.convertAuthToken(refreshToken); + // refresh token이 존재하지 않을 때 = 로그인 상태가 아닐 때 + if (refreshToken == null) { + throw new CustomException(ErrorCode.REFRESH_TOKEN_NOT_EXIST); + } + + AuthToken authRefreshToken = tokenProvider.convertRefreshToken(refreshToken); + + Date now = new Date(); + + // Refresh Token이 만료되었을 때 + if (authRefreshToken.getExpiredTokenClaims().getExpiration().getTime() <= now.getTime()) { + throw new CustomException(ErrorCode.EXPIRED_REFRESH_TOKEN); + } + + // Refresh Token이 유효하지 않을 때 if (authRefreshToken.getToken() == null || !authRefreshToken.tokenValidate()) { throw new CustomException(ErrorCode.INVALID_REFRESH_TOKEN); } @@ -72,8 +84,6 @@ public AuthResponse refreshToken(HttpServletRequest request, HttpServletResponse } // Access token 재발급 - Date now = new Date(); - AuthToken newAccessToken = tokenProvider.createAuthToken( userId, roleType.getCode(), @@ -81,7 +91,7 @@ public AuthResponse refreshToken(HttpServletRequest request, HttpServletResponse ); - // refresh 토큰 유효기간 가져오기 + // refresh 토큰 유효기간 설정값 가져오기 long refreshTokenExpiry = appProperties.getAuth().getRefreshTokenExpiry(); // refresh 토큰 생성