From 79c5d71de7b75905c42939e0323183ccbb9ecd25 Mon Sep 17 00:00:00 2001 From: sese2204 Date: Wed, 19 Feb 2025 16:48:09 +0900 Subject: [PATCH 01/10] =?UTF-8?q?refactor(exception):=20=EC=9C=A0=ED=9A=A8?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EC=9D=80=20=EB=A6=AC=ED=94=84?= =?UTF-8?q?=EB=A0=88=EC=89=AC=20=ED=86=A0=ED=81=B0=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InvalidRefreshTokenException.java | 9 +++++++ .../web/controller/AuthController.java | 25 ++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/pickyfy/pickyfy/exception/InvalidRefreshTokenException.java diff --git a/src/main/java/com/pickyfy/pickyfy/exception/InvalidRefreshTokenException.java b/src/main/java/com/pickyfy/pickyfy/exception/InvalidRefreshTokenException.java new file mode 100644 index 0000000..cae923f --- /dev/null +++ b/src/main/java/com/pickyfy/pickyfy/exception/InvalidRefreshTokenException.java @@ -0,0 +1,9 @@ +package com.pickyfy.pickyfy.exception; + +import com.pickyfy.pickyfy.web.apiResponse.common.BaseErrorCode; + +public class InvalidRefreshTokenException extends GeneralException { + public InvalidRefreshTokenException(BaseErrorCode baseErrorCode) { + super(baseErrorCode); + } +} diff --git a/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java b/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java index 6b133a6..310ab40 100644 --- a/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java +++ b/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java @@ -1,10 +1,14 @@ package com.pickyfy.pickyfy.web.controller; import com.pickyfy.pickyfy.common.Constant; +import com.pickyfy.pickyfy.exception.InvalidRefreshTokenException; import com.pickyfy.pickyfy.service.AuthService; import com.pickyfy.pickyfy.web.apiResponse.common.ApiResponse; +import com.pickyfy.pickyfy.web.apiResponse.error.ErrorStatus; import com.pickyfy.pickyfy.web.apiResponse.success.SuccessStatus; import com.pickyfy.pickyfy.web.dto.response.AuthResponse; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.JwtException; import io.swagger.v3.oas.annotations.Parameter; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; @@ -42,13 +46,22 @@ public ApiResponse reIssue( HttpServletResponse response) { if (refreshToken == null) { - return ApiResponse.onFailure("400","리프레시 토큰이 없습니다.", null); + throw new InvalidRefreshTokenException(ErrorStatus.TOKEN_INVALID); + } + try { + AuthResponse authResponse = authService.reIssue(refreshToken); + response.setHeader("Authorization", "Bearer " + authResponse.accessToken()); + createCookie(response, authResponse.refreshToken()); + return ApiResponse.onSuccess(SuccessStatus.REISSUE_TOKEN_SUCCESS, null); + } catch (ExpiredJwtException e) { + // 리프레시 토큰이 만료된 경우 + clearCookie(response); // 만료된 토큰 쿠키 제거 + throw new InvalidRefreshTokenException(ErrorStatus.TOKEN_EXPIRATION); + } catch (JwtException e) { + // 리프레시 토큰이 유효하지 않은 경우 + clearCookie(response); // 유효하지 않은 토큰 쿠키 제거 + throw new InvalidRefreshTokenException(ErrorStatus.TOKEN_INVALID); } - AuthResponse authResponse = authService.reIssue(refreshToken); - response.setHeader("Authorization", "Bearer " + authResponse.accessToken()); - createCookie(response, authResponse.refreshToken()); - - return ApiResponse.onSuccess(SuccessStatus.REISSUE_TOKEN_SUCCESS, null); } @Override From 0a484735b7f48c0db3449fd7cb87ec2f547fa8c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=91=ED=9A=A8=EB=B9=88?= Date: Wed, 19 Feb 2025 21:42:52 +0900 Subject: [PATCH 02/10] =?UTF-8?q?[fix]=20=EA=B8=80=EB=A1=9C=EB=B2=8C=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=9D=91=EB=8B=B5=EC=9D=84=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=ED=95=98=EA=B2=8C=20=EB=A7=8C=EB=93=A4=EC=96=B4?= =?UTF-8?q?=EB=B3=B4=EC=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/DuplicateResourceException.java | 6 +-- .../pickyfy/exception/ExceptionHandler.java | 6 +-- .../pickyfy/exception/GeneralException.java | 10 +---- .../exception/GlobalExceptionHandler.java | 42 +++++++++---------- .../InvalidRefreshTokenException.java | 6 +-- .../pickyfy/service/AuthServiceImpl.java | 25 +++++++---- .../web/apiResponse/common/ApiResponse.java | 9 +++- .../web/controller/AuthController.java | 20 ++------- 8 files changed, 61 insertions(+), 63 deletions(-) diff --git a/src/main/java/com/pickyfy/pickyfy/exception/DuplicateResourceException.java b/src/main/java/com/pickyfy/pickyfy/exception/DuplicateResourceException.java index 403913c..a08f908 100644 --- a/src/main/java/com/pickyfy/pickyfy/exception/DuplicateResourceException.java +++ b/src/main/java/com/pickyfy/pickyfy/exception/DuplicateResourceException.java @@ -1,9 +1,9 @@ package com.pickyfy.pickyfy.exception; -import com.pickyfy.pickyfy.web.apiResponse.common.BaseErrorCode; +import com.pickyfy.pickyfy.web.apiResponse.error.ErrorStatus; public class DuplicateResourceException extends GeneralException { - public DuplicateResourceException(BaseErrorCode baseErrorCode) { - super(baseErrorCode); + public DuplicateResourceException(ErrorStatus errorStatus) { + super(errorStatus); } } diff --git a/src/main/java/com/pickyfy/pickyfy/exception/ExceptionHandler.java b/src/main/java/com/pickyfy/pickyfy/exception/ExceptionHandler.java index a904197..3e0eb7d 100644 --- a/src/main/java/com/pickyfy/pickyfy/exception/ExceptionHandler.java +++ b/src/main/java/com/pickyfy/pickyfy/exception/ExceptionHandler.java @@ -1,9 +1,9 @@ package com.pickyfy.pickyfy.exception; -import com.pickyfy.pickyfy.web.apiResponse.common.BaseErrorCode; +import com.pickyfy.pickyfy.web.apiResponse.error.ErrorStatus; public class ExceptionHandler extends GeneralException { - public ExceptionHandler(BaseErrorCode errorCode){ - super(errorCode); + public ExceptionHandler(ErrorStatus errorStatus){ + super(errorStatus); } } \ No newline at end of file diff --git a/src/main/java/com/pickyfy/pickyfy/exception/GeneralException.java b/src/main/java/com/pickyfy/pickyfy/exception/GeneralException.java index 5db0c33..1fee476 100644 --- a/src/main/java/com/pickyfy/pickyfy/exception/GeneralException.java +++ b/src/main/java/com/pickyfy/pickyfy/exception/GeneralException.java @@ -1,17 +1,11 @@ package com.pickyfy.pickyfy.exception; -import com.pickyfy.pickyfy.web.apiResponse.common.BaseErrorCode; -import com.pickyfy.pickyfy.web.apiResponse.error.ErrorResponse; +import com.pickyfy.pickyfy.web.apiResponse.error.ErrorStatus; import lombok.AllArgsConstructor; import lombok.Getter; @Getter @AllArgsConstructor public class GeneralException extends RuntimeException { - - private BaseErrorCode code; - - public ErrorResponse getErrorReason(){ - return this.code.getReason(); - } + private final ErrorStatus errorStatus; } diff --git a/src/main/java/com/pickyfy/pickyfy/exception/GlobalExceptionHandler.java b/src/main/java/com/pickyfy/pickyfy/exception/GlobalExceptionHandler.java index 11c3795..5445b5f 100644 --- a/src/main/java/com/pickyfy/pickyfy/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/pickyfy/pickyfy/exception/GlobalExceptionHandler.java @@ -1,9 +1,9 @@ package com.pickyfy.pickyfy.exception; import com.pickyfy.pickyfy.web.apiResponse.common.ApiResponse; -import com.pickyfy.pickyfy.web.apiResponse.error.ErrorResponse; import com.pickyfy.pickyfy.web.apiResponse.error.ErrorStatus; import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.ConstraintViolation; import lombok.extern.slf4j.Slf4j; import jakarta.validation.ConstraintViolationException; import org.springframework.http.HttpHeaders; @@ -29,7 +29,7 @@ public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { @ExceptionHandler public ResponseEntity handleConstraintViolation(ConstraintViolationException e, WebRequest request){ String errorMessage = e.getConstraintViolations().stream() - .map(constraintViolation -> constraintViolation.getMessage()) + .map(ConstraintViolation::getMessage) .findFirst() .orElseThrow(() -> new RuntimeException("ConstraintViolationException 추출 도중 에러 발생")); @@ -41,7 +41,7 @@ public ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotVali Map errors = new LinkedHashMap<>(); - e.getBindingResult().getFieldErrors().stream() + e.getBindingResult().getFieldErrors() .forEach(fieldError -> { String fieldName = fieldError.getField(); String errorMessage = Optional.ofNullable(fieldError.getDefaultMessage()).orElse(""); @@ -52,9 +52,8 @@ public ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotVali } @ExceptionHandler(value = GeneralException.class) - public ResponseEntity handleOnThrowException(GeneralException generalException, HttpServletRequest request) { - ErrorResponse errorReasonHttpStatus = generalException.getErrorReason(); - return buildOnThrowExceptionResponse(generalException,errorReasonHttpStatus,null,request); + public ResponseEntity handleOnThrowException(GeneralException generalException, HttpServletRequest request) { + return buildOnThrowExceptionResponse(generalException, generalException.getErrorStatus(),null,request); } @ExceptionHandler @@ -63,33 +62,34 @@ public ResponseEntity handleUnexpectedException(Exception e, WebRequest return buildUnexpectedExceptionResponse(e, ErrorStatus._INTERNAL_SERVER_ERROR, HttpHeaders.EMPTY, ErrorStatus._INTERNAL_SERVER_ERROR.getHttpStatus(),request, e.getMessage()); } - private ResponseEntity buildConstraintViolationResponse(Exception e, ErrorStatus errorCommonStatus, - HttpHeaders headers, WebRequest request) { - ApiResponse body = ApiResponse.onFailure(errorCommonStatus.getCode(), errorCommonStatus.getMessage(), null); + private ResponseEntity buildConstraintViolationResponse(Exception e, ErrorStatus errorStatus, + HttpHeaders headers, WebRequest request) { + ApiResponse body = ApiResponse.onFailure(errorStatus, null); return super.handleExceptionInternal( e, body, headers, - errorCommonStatus.getHttpStatus(), + errorStatus.getHttpStatus(), request ); } - private ResponseEntity buildInvalidMethodArgumentResponse(Exception e, HttpHeaders headers, ErrorStatus errorCommonStatus, - WebRequest request, Map errorArgs) { - ApiResponse body = ApiResponse.onFailure(errorCommonStatus.getCode(),errorCommonStatus.getMessage(),errorArgs); + private ResponseEntity buildInvalidMethodArgumentResponse(Exception e, HttpHeaders headers, ErrorStatus errorStatus, + WebRequest request, Map errorArgs) { + + ApiResponse body = ApiResponse.onFailure(errorStatus, errorArgs); return super.handleExceptionInternal( e, body, headers, - errorCommonStatus.getHttpStatus(), + errorStatus.getHttpStatus(), request ); } - private ResponseEntity buildUnexpectedExceptionResponse(Exception e, ErrorStatus errorCommonStatus, - HttpHeaders headers, HttpStatus status, WebRequest request, String errorPoint) { - ApiResponse body = ApiResponse.onFailure(errorCommonStatus.getCode(),errorCommonStatus.getMessage(),errorPoint); + private ResponseEntity buildUnexpectedExceptionResponse(Exception e, ErrorStatus errorStatus, + HttpHeaders headers, HttpStatus status, WebRequest request, String errorPoint) { + ApiResponse body = ApiResponse.onFailure(errorStatus, errorPoint); return super.handleExceptionInternal( e, body, @@ -99,10 +99,10 @@ private ResponseEntity buildUnexpectedExceptionResponse(Exception e, Err ); } - private ResponseEntity buildOnThrowExceptionResponse(Exception e, ErrorResponse reason, - HttpHeaders headers, HttpServletRequest request) { + private ResponseEntity buildOnThrowExceptionResponse(Exception e, ErrorStatus errorStatus, + HttpHeaders headers, HttpServletRequest request) { - ApiResponse body = ApiResponse.onFailure(reason.getCode(),reason.getMessage(),null); + ApiResponse body = ApiResponse.onFailure(errorStatus, null); WebRequest webRequest = new ServletWebRequest(request); return super.handleExceptionInternal( @@ -113,4 +113,4 @@ private ResponseEntity buildOnThrowExceptionResponse(Exception e, ErrorR webRequest ); } -} \ No newline at end of file +} diff --git a/src/main/java/com/pickyfy/pickyfy/exception/InvalidRefreshTokenException.java b/src/main/java/com/pickyfy/pickyfy/exception/InvalidRefreshTokenException.java index cae923f..cdd2f1b 100644 --- a/src/main/java/com/pickyfy/pickyfy/exception/InvalidRefreshTokenException.java +++ b/src/main/java/com/pickyfy/pickyfy/exception/InvalidRefreshTokenException.java @@ -1,9 +1,9 @@ package com.pickyfy.pickyfy.exception; -import com.pickyfy.pickyfy.web.apiResponse.common.BaseErrorCode; +import com.pickyfy.pickyfy.web.apiResponse.error.ErrorStatus; public class InvalidRefreshTokenException extends GeneralException { - public InvalidRefreshTokenException(BaseErrorCode baseErrorCode) { - super(baseErrorCode); + public InvalidRefreshTokenException(ErrorStatus errorStatus) { + super(errorStatus); } } diff --git a/src/main/java/com/pickyfy/pickyfy/service/AuthServiceImpl.java b/src/main/java/com/pickyfy/pickyfy/service/AuthServiceImpl.java index 691b7e2..fd332a0 100644 --- a/src/main/java/com/pickyfy/pickyfy/service/AuthServiceImpl.java +++ b/src/main/java/com/pickyfy/pickyfy/service/AuthServiceImpl.java @@ -4,8 +4,11 @@ import com.pickyfy.pickyfy.common.util.JwtUtil; import com.pickyfy.pickyfy.common.util.RedisUtil; import com.pickyfy.pickyfy.exception.ExceptionHandler; +import com.pickyfy.pickyfy.exception.GeneralException; import com.pickyfy.pickyfy.web.apiResponse.error.ErrorStatus; import com.pickyfy.pickyfy.web.dto.response.AuthResponse; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.JwtException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -23,13 +26,21 @@ public void logout(String refreshToken){ @Override public AuthResponse reIssue(String token){ - validateRefreshToken(token); - String principal = jwtUtil.getPrincipal(token); - String accessToken = jwtUtil.createAccessToken(principal, jwtUtil.getRole(token)); - String refreshToken = jwtUtil.createRefreshToken(principal, jwtUtil.getRole(token)); - - redisUtil.setData("refresh:" + jwtUtil.getPrincipal(refreshToken), refreshToken, Constant.REFRESH_TOKEN_EXPIRATION_TIME); - return AuthResponse.from(accessToken, refreshToken); + try { + validateRefreshToken(token); + String principal = jwtUtil.getPrincipal(token); + String accessToken = jwtUtil.createAccessToken(principal, jwtUtil.getRole(token)); + String refreshToken = jwtUtil.createRefreshToken(principal, jwtUtil.getRole(token)); + + redisUtil.setData("refresh:" + jwtUtil.getPrincipal(refreshToken), refreshToken, Constant.REFRESH_TOKEN_EXPIRATION_TIME); + return AuthResponse.from(accessToken, refreshToken); + } catch (ExpiredJwtException e) { + // 만료된 리프레시 토큰 + throw new GeneralException(ErrorStatus.TOKEN_EXPIRATION); + } catch (JwtException e) { + // 유효하지 않은 리프레시 토큰 + throw new GeneralException(ErrorStatus.TOKEN_INVALID); + } } @Override diff --git a/src/main/java/com/pickyfy/pickyfy/web/apiResponse/common/ApiResponse.java b/src/main/java/com/pickyfy/pickyfy/web/apiResponse/common/ApiResponse.java index a037b4b..d264a56 100644 --- a/src/main/java/com/pickyfy/pickyfy/web/apiResponse/common/ApiResponse.java +++ b/src/main/java/com/pickyfy/pickyfy/web/apiResponse/common/ApiResponse.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.pickyfy.pickyfy.web.apiResponse.error.ErrorStatus; import com.pickyfy.pickyfy.web.apiResponse.success.SuccessStatus; import lombok.AllArgsConstructor; import lombok.Getter; @@ -25,7 +26,11 @@ public static ApiResponse onSuccess(SuccessStatus status, T result) { return new ApiResponse<>(true, status.getCode(), status.getMessage(), result); } - public static ApiResponse onFailure(String code, String message, T data){ - return new ApiResponse<>(false, code, message, data); + public static ApiResponse onFailure(T result){ + return new ApiResponse<>(false, ErrorStatus._INTERNAL_SERVER_ERROR.getCode(), ErrorStatus._INTERNAL_SERVER_ERROR.getMessage(), result); + } + + public static ApiResponse onFailure(ErrorStatus status, T result){ + return new ApiResponse<>(false, status.getCode(), status.getMessage(), result); } } diff --git a/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java b/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java index 310ab40..56b688b 100644 --- a/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java +++ b/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java @@ -7,8 +7,6 @@ import com.pickyfy.pickyfy.web.apiResponse.error.ErrorStatus; import com.pickyfy.pickyfy.web.apiResponse.success.SuccessStatus; import com.pickyfy.pickyfy.web.dto.response.AuthResponse; -import io.jsonwebtoken.ExpiredJwtException; -import io.jsonwebtoken.JwtException; import io.swagger.v3.oas.annotations.Parameter; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; @@ -48,20 +46,10 @@ public ApiResponse reIssue( if (refreshToken == null) { throw new InvalidRefreshTokenException(ErrorStatus.TOKEN_INVALID); } - try { - AuthResponse authResponse = authService.reIssue(refreshToken); - response.setHeader("Authorization", "Bearer " + authResponse.accessToken()); - createCookie(response, authResponse.refreshToken()); - return ApiResponse.onSuccess(SuccessStatus.REISSUE_TOKEN_SUCCESS, null); - } catch (ExpiredJwtException e) { - // 리프레시 토큰이 만료된 경우 - clearCookie(response); // 만료된 토큰 쿠키 제거 - throw new InvalidRefreshTokenException(ErrorStatus.TOKEN_EXPIRATION); - } catch (JwtException e) { - // 리프레시 토큰이 유효하지 않은 경우 - clearCookie(response); // 유효하지 않은 토큰 쿠키 제거 - throw new InvalidRefreshTokenException(ErrorStatus.TOKEN_INVALID); - } + AuthResponse authResponse = authService.reIssue(refreshToken); // 서비스 메서드 호출 + response.setHeader("Authorization", "Bearer " + authResponse.accessToken()); + createCookie(response, authResponse.refreshToken()); + return ApiResponse.onSuccess(SuccessStatus.REISSUE_TOKEN_SUCCESS, null); } @Override From 73133b41f0d89bdc520a58a1447a552800180528 Mon Sep 17 00:00:00 2001 From: SeungGyu Date: Wed, 19 Feb 2025 23:33:38 +0900 Subject: [PATCH 03/10] =?UTF-8?q?[refactor]=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EC=9E=AC=EB=B0=9C=EA=B8=89=20=EC=8B=9C=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EB=A6=AC=ED=94=84=EB=A0=88=EC=8B=9C=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pickyfy/web/controller/AuthController.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java b/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java index 56b688b..4cbdacb 100644 --- a/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java +++ b/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java @@ -48,7 +48,7 @@ public ApiResponse reIssue( } AuthResponse authResponse = authService.reIssue(refreshToken); // 서비스 메서드 호출 response.setHeader("Authorization", "Bearer " + authResponse.accessToken()); - createCookie(response, authResponse.refreshToken()); + createCookie(response, authResponse); return ApiResponse.onSuccess(SuccessStatus.REISSUE_TOKEN_SUCCESS, null); } @@ -60,16 +60,25 @@ public ApiResponse isAuthenticated( return ApiResponse.onSuccess(isAuthenticated); } - private void createCookie(HttpServletResponse response, String refreshToken) { - ResponseCookie expiredCookie = ResponseCookie.from(REFRESH_TOKEN_COOKIE_NAME, refreshToken) + private void createCookie(HttpServletResponse response, AuthResponse token) { + ResponseCookie expiredAccessToken = ResponseCookie.from(ACCESS_TOKEN_COOKIE_NAME, token.accessToken()) .httpOnly(true) .secure(true) .sameSite("None") .path("/") + .maxAge(Duration.ofMillis(Constant.ACCESS_TOKEN_EXPIRATION_TIME).getSeconds()) + .build(); + + ResponseCookie expiredRefreshToken = ResponseCookie.from(REFRESH_TOKEN_COOKIE_NAME, token.refreshToken()) + .httpOnly(true) + .secure(true) + .sameSite("None") + .path("/auth") .maxAge(Duration.ofMillis(Constant.REFRESH_TOKEN_EXPIRATION_TIME).getSeconds()) .build(); - response.setHeader(HttpHeaders.SET_COOKIE, expiredCookie.toString()); + response.addHeader(HttpHeaders.SET_COOKIE, expiredAccessToken.toString()); + response.addHeader(HttpHeaders.SET_COOKIE, expiredRefreshToken.toString()); } private void clearCookie(HttpServletResponse response) { From 7f8ade25511e6247e0aa972c676ede7a22298871 Mon Sep 17 00:00:00 2001 From: SeungGyu Date: Thu, 20 Feb 2025 00:43:30 +0900 Subject: [PATCH 04/10] =?UTF-8?q?[refactor]=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EC=9E=AC=EB=B0=9C=EA=B8=89=20=EC=8B=9C=20=EC=97=91=EC=84=B8?= =?UTF-8?q?=EC=8A=A4=ED=86=A0=ED=81=B0=20=ED=97=A4=EB=8D=94=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=20=EB=A1=9C=EC=A7=81=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/pickyfy/pickyfy/web/controller/AuthController.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java b/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java index 4cbdacb..6b08b91 100644 --- a/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java +++ b/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java @@ -46,8 +46,7 @@ public ApiResponse reIssue( if (refreshToken == null) { throw new InvalidRefreshTokenException(ErrorStatus.TOKEN_INVALID); } - AuthResponse authResponse = authService.reIssue(refreshToken); // 서비스 메서드 호출 - response.setHeader("Authorization", "Bearer " + authResponse.accessToken()); + AuthResponse authResponse = authService.reIssue(refreshToken); createCookie(response, authResponse); return ApiResponse.onSuccess(SuccessStatus.REISSUE_TOKEN_SUCCESS, null); } @@ -66,7 +65,7 @@ private void createCookie(HttpServletResponse response, AuthResponse token) { .secure(true) .sameSite("None") .path("/") - .maxAge(Duration.ofMillis(Constant.ACCESS_TOKEN_EXPIRATION_TIME).getSeconds()) + .maxAge(Duration.ofMillis(Constant.COOKIE_EXPIRATION).getSeconds()) .build(); ResponseCookie expiredRefreshToken = ResponseCookie.from(REFRESH_TOKEN_COOKIE_NAME, token.refreshToken()) @@ -74,7 +73,7 @@ private void createCookie(HttpServletResponse response, AuthResponse token) { .secure(true) .sameSite("None") .path("/auth") - .maxAge(Duration.ofMillis(Constant.REFRESH_TOKEN_EXPIRATION_TIME).getSeconds()) + .maxAge(Duration.ofMillis(Constant.COOKIE_EXPIRATION).getSeconds()) .build(); response.addHeader(HttpHeaders.SET_COOKIE, expiredAccessToken.toString()); From 302956f9f70ca00cce764191f01d85d03e952f83 Mon Sep 17 00:00:00 2001 From: SeungGyu Date: Thu, 20 Feb 2025 00:44:30 +0900 Subject: [PATCH 05/10] =?UTF-8?q?[refactor]=20=EC=BF=A0=ED=82=A4=20maxAge?= =?UTF-8?q?=20=EC=97=B0=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pickyfy/pickyfy/auth/filter/CustomLoginFilter.java | 8 ++++---- .../pickyfy/auth/handler/OAuth2SuccessHandler.java | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/pickyfy/pickyfy/auth/filter/CustomLoginFilter.java b/src/main/java/com/pickyfy/pickyfy/auth/filter/CustomLoginFilter.java index 902fcff..4d8e98f 100644 --- a/src/main/java/com/pickyfy/pickyfy/auth/filter/CustomLoginFilter.java +++ b/src/main/java/com/pickyfy/pickyfy/auth/filter/CustomLoginFilter.java @@ -62,9 +62,9 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR redisUtil.setData("refresh:" + jwtUtil.getPrincipal(refreshToken), refreshToken, Constant.REFRESH_TOKEN_EXPIRATION_TIME); setBody(role, response); - ResponseCookie accessCookie = createCookie("accessToken", accessToken, Constant.ACCESS_TOKEN_EXPIRATION_TIME, "/"); + ResponseCookie accessCookie = createCookie("accessToken", accessToken,"/"); response.addHeader(HttpHeaders.SET_COOKIE, accessCookie.toString()); - ResponseCookie refreshCookie = createCookie("refreshToken", refreshToken, Constant.REFRESH_TOKEN_EXPIRATION_TIME, "/auth"); + ResponseCookie refreshCookie = createCookie("refreshToken", refreshToken, "/auth"); response.addHeader(HttpHeaders.SET_COOKIE, refreshCookie.toString()); } @@ -84,13 +84,13 @@ private void setBody(String role, HttpServletResponse response) throws IOExcepti """, role)); } - private ResponseCookie createCookie(String name, String token, long expirationTime, String path) { + private ResponseCookie createCookie(String name, String token, String path) { return ResponseCookie.from(name, token) .httpOnly(true) .secure(true) .sameSite("None") .path(path) - .maxAge(Duration.ofMillis(expirationTime).getSeconds()) + .maxAge(Duration.ofMillis(Constant.COOKIE_EXPIRATION).getSeconds()) .build(); } } \ No newline at end of file diff --git a/src/main/java/com/pickyfy/pickyfy/auth/handler/OAuth2SuccessHandler.java b/src/main/java/com/pickyfy/pickyfy/auth/handler/OAuth2SuccessHandler.java index 7c84e9e..0c33a1c 100644 --- a/src/main/java/com/pickyfy/pickyfy/auth/handler/OAuth2SuccessHandler.java +++ b/src/main/java/com/pickyfy/pickyfy/auth/handler/OAuth2SuccessHandler.java @@ -37,22 +37,22 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo redisUtil.setData("refresh:" + email, refreshToken, Constant.REFRESH_TOKEN_EXPIRATION_TIME); - ResponseCookie accessCookie = createCookie("accessToken", accessToken, Constant.ACCESS_TOKEN_EXPIRATION_TIME, "/"); + ResponseCookie accessCookie = createCookie("accessToken", accessToken, "/"); response.addHeader(HttpHeaders.SET_COOKIE, accessCookie.toString()); - ResponseCookie refreshCookie = createCookie("refreshToken", refreshToken, Constant.REFRESH_TOKEN_EXPIRATION_TIME, "/auth"); + ResponseCookie refreshCookie = createCookie("refreshToken", refreshToken, "/auth"); response.addHeader(HttpHeaders.SET_COOKIE, refreshCookie.toString()); response.sendRedirect(REDIRECT_URL); SecurityContextHolder.getContext().setAuthentication(authentication); } - private ResponseCookie createCookie(String name, String token, long expirationTime, String path) { + private ResponseCookie createCookie(String name, String token, String path) { return ResponseCookie.from(name, token) .httpOnly(true) .secure(true) .sameSite("None") .path(path) - .maxAge(Duration.ofMillis(expirationTime).getSeconds()) + .maxAge(Duration.ofMillis(Constant.COOKIE_EXPIRATION).getSeconds()) .build(); } } \ No newline at end of file From bb771a5bbdeb07230f63e9a52c0d5fd8dc8d47a6 Mon Sep 17 00:00:00 2001 From: SeungGyu Date: Thu, 20 Feb 2025 04:19:49 +0900 Subject: [PATCH 06/10] =?UTF-8?q?[refactor]=20jwtUtil=20=ED=86=A0=ED=81=B0?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=20=EB=A9=94=EC=84=9C=EB=93=9C(=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC=20x)=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pickyfy/pickyfy/common/util/JwtUtil.java | 49 ++++++++++++++----- .../web/controller/AuthController.java | 2 +- .../dto/response/TokenValidationResult.java | 11 +++++ 3 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/pickyfy/pickyfy/web/dto/response/TokenValidationResult.java diff --git a/src/main/java/com/pickyfy/pickyfy/common/util/JwtUtil.java b/src/main/java/com/pickyfy/pickyfy/common/util/JwtUtil.java index d406e88..110e9de 100644 --- a/src/main/java/com/pickyfy/pickyfy/common/util/JwtUtil.java +++ b/src/main/java/com/pickyfy/pickyfy/common/util/JwtUtil.java @@ -3,6 +3,7 @@ import com.pickyfy.pickyfy.web.apiResponse.error.ErrorStatus; import com.pickyfy.pickyfy.common.Constant; import com.pickyfy.pickyfy.exception.ExceptionHandler; +import com.pickyfy.pickyfy.web.dto.response.TokenValidationResult; import io.jsonwebtoken.*; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; @@ -14,6 +15,8 @@ import javax.crypto.SecretKey; import java.security.Key; import java.util.Date; +import java.util.HashMap; +import java.util.Map; @Slf4j @Component @@ -72,21 +75,42 @@ private String createToken(String principal, String role, long expireTime, Strin .compact(); } - public boolean validateToken(String token) { // 예외처리 추가 + public void validateToken(String token) { try { Jwts.parser().verifyWith((SecretKey) key).build().parseSignedClaims(token); - return true; - } catch (SecurityException | MalformedJwtException e) { - log.info("잘못된 서명 혹은 JWT 형식 오류", e); - } catch (ExpiredJwtException e) { - log.info("토큰 만료", e); - throw new ExceptionHandler(ErrorStatus.TOKEN_EXPIRATION); - } catch (UnsupportedJwtException e) { - log.info("지원하지 않는 서명 알고리즘", e); - } catch (IllegalArgumentException e) { - log.info("올바르지 않은 값 입력(토큰 문자열 null)", e); + TokenValidationResult.success("검증 완료."); + } catch (Exception e) { + handleJwtException(e, true); + } + } + + public TokenValidationResult validateTokenWithoutException(String token) { + try { + Jwts.parser().verifyWith((SecretKey) key).build().parseSignedClaims(token); + return TokenValidationResult.success("검증 완료."); + } catch (Exception e) { + return handleJwtException(e, false); + } + } + + private TokenValidationResult handleJwtException(Exception e, boolean throwException) { + Map, String> errorMessages = new HashMap<>(); + errorMessages.put(SecurityException.class, "유효하지 않은 토큰입니다."); + errorMessages.put(MalformedJwtException.class, "유효하지 않은 토큰입니다."); + errorMessages.put(UnsupportedJwtException.class, "유효하지 않은 토큰입니다."); + errorMessages.put(IllegalArgumentException.class, "유효하지 않은 토큰입니다."); + errorMessages.put(ExpiredJwtException.class, "토큰 만료"); + + String message = errorMessages.getOrDefault(e.getClass(), "알 수 없는 JWT 오류"); + log.info(message, e); + + if (throwException) { + throw new ExceptionHandler( + e instanceof ExpiredJwtException ? ErrorStatus.TOKEN_EXPIRATION : ErrorStatus.TOKEN_INVALID + ); } - return false; + + return TokenValidationResult.failure(message); } public Claims parseClaims(String token) { @@ -108,5 +132,4 @@ public String getPrincipal(String token) { public String getRole(String token) { return parseClaims(token).get(ROLE, String.class); } - } \ No newline at end of file diff --git a/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java b/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java index 6b08b91..1658ee9 100644 --- a/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java +++ b/src/main/java/com/pickyfy/pickyfy/web/controller/AuthController.java @@ -100,4 +100,4 @@ private void clearCookie(HttpServletResponse response) { response.addHeader(HttpHeaders.SET_COOKIE, expiredAccessToken.toString()); response.addHeader(HttpHeaders.SET_COOKIE, expiredRefreshToken.toString()); } -} +} \ No newline at end of file diff --git a/src/main/java/com/pickyfy/pickyfy/web/dto/response/TokenValidationResult.java b/src/main/java/com/pickyfy/pickyfy/web/dto/response/TokenValidationResult.java new file mode 100644 index 0000000..46486a2 --- /dev/null +++ b/src/main/java/com/pickyfy/pickyfy/web/dto/response/TokenValidationResult.java @@ -0,0 +1,11 @@ +package com.pickyfy.pickyfy.web.dto.response; + +public record TokenValidationResult(boolean isValid, String message) { + public static TokenValidationResult success(String message) { + return new TokenValidationResult(true, message); + } + + public static TokenValidationResult failure(String message) { + return new TokenValidationResult(false, message); + } +} \ No newline at end of file From bf806bf5b4a3057ce0d1dee395b7abf9a4792391 Mon Sep 17 00:00:00 2001 From: SeungGyu Date: Thu, 20 Feb 2025 04:24:19 +0900 Subject: [PATCH 07/10] =?UTF-8?q?[chore]=20SecurityConfig=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=95=84=EC=9B=83=20=EC=97=94=EB=93=9C=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EA=B3=B5=EA=B0=9C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/pickyfy/pickyfy/common/config/SecurityConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/pickyfy/pickyfy/common/config/SecurityConfig.java b/src/main/java/com/pickyfy/pickyfy/common/config/SecurityConfig.java index 10a7071..39a7119 100644 --- a/src/main/java/com/pickyfy/pickyfy/common/config/SecurityConfig.java +++ b/src/main/java/com/pickyfy/pickyfy/common/config/SecurityConfig.java @@ -54,7 +54,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .authorizeHttpRequests((auth) -> auth .requestMatchers("/", "/swagger-ui/**", "/v3/api-docs/**").permitAll() .requestMatchers("/users/signup", "/auth/login", "/email-auth/**", "/auth/reissue", "/users/verify-by-email", "/users/reset-password").permitAll() - .requestMatchers("/auth/oauth2/**", "/oauth2/callback", "/auth/me").permitAll() + .requestMatchers("/auth/oauth2/**", "/oauth2/callback", "/auth/me", "/auth/logout").permitAll() .requestMatchers("/actuator/**", "/actuator/prometheus").permitAll() .requestMatchers("/admin/**").hasAuthority("ADMIN") .anyRequest().authenticated() From 6a13778ae515d55374d0c0e5285a882998151d36 Mon Sep 17 00:00:00 2001 From: SeungGyu Date: Thu, 20 Feb 2025 04:24:45 +0900 Subject: [PATCH 08/10] =?UTF-8?q?[chore]=20=EC=BF=A0=ED=82=A4=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=EA=B8=B0=EA=B0=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/pickyfy/pickyfy/common/Constant.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/pickyfy/pickyfy/common/Constant.java b/src/main/java/com/pickyfy/pickyfy/common/Constant.java index 6911102..73100fc 100644 --- a/src/main/java/com/pickyfy/pickyfy/common/Constant.java +++ b/src/main/java/com/pickyfy/pickyfy/common/Constant.java @@ -14,5 +14,7 @@ public class Constant { public static final long PLACES_EXPIRATION_TIME = 30 * 60 * 1000; public static final long PLACE_EXPIRATION_TIME = 30 * 60 * 1000; + public static final long COOKIE_EXPIRATION = 4 * 24 * 60 * 60 * 1000; + public static final String REDIS_KEY_PREFIX = "refresh:"; } From a7b4bb56aa6e13d3a55bb6b30624f041d16e7639 Mon Sep 17 00:00:00 2001 From: SeungGyu Date: Thu, 20 Feb 2025 04:25:28 +0900 Subject: [PATCH 09/10] =?UTF-8?q?[fix]=20GlobalExceptionHandler=20null=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/pickyfy/pickyfy/exception/GlobalExceptionHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/pickyfy/pickyfy/exception/GlobalExceptionHandler.java b/src/main/java/com/pickyfy/pickyfy/exception/GlobalExceptionHandler.java index 5445b5f..e5eecc0 100644 --- a/src/main/java/com/pickyfy/pickyfy/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/pickyfy/pickyfy/exception/GlobalExceptionHandler.java @@ -53,7 +53,7 @@ public ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotVali @ExceptionHandler(value = GeneralException.class) public ResponseEntity handleOnThrowException(GeneralException generalException, HttpServletRequest request) { - return buildOnThrowExceptionResponse(generalException, generalException.getErrorStatus(),null,request); + return buildOnThrowExceptionResponse(generalException, generalException.getErrorStatus(),null, request); } @ExceptionHandler @@ -109,7 +109,7 @@ private ResponseEntity buildOnThrowExceptionResponse(Exception e, ErrorS e, body, headers, - null, + errorStatus.getHttpStatus(), webRequest ); } From 82f9544de5a5028f55f6bfaf9310a3f4052cc284 Mon Sep 17 00:00:00 2001 From: SeungGyu Date: Thu, 20 Feb 2025 04:48:07 +0900 Subject: [PATCH 10/10] =?UTF-8?q?[refactor]=20CustomAuthenticationEntryPoi?= =?UTF-8?q?nt=20=EC=9D=91=EB=8B=B5=EA=B0=92=20=EC=84=B8=EB=B6=80=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/filter/CustomLoginFilter.java | 2 +- .../pickyfy/auth/filter/JwtAuthFilter.java | 10 ++++++- .../CustomAuthenticationEntryPoint.java | 21 ++++++++++---- .../pickyfy/service/AuthServiceImpl.java | 29 ++++++------------- 4 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/pickyfy/pickyfy/auth/filter/CustomLoginFilter.java b/src/main/java/com/pickyfy/pickyfy/auth/filter/CustomLoginFilter.java index 4d8e98f..af71b1e 100644 --- a/src/main/java/com/pickyfy/pickyfy/auth/filter/CustomLoginFilter.java +++ b/src/main/java/com/pickyfy/pickyfy/auth/filter/CustomLoginFilter.java @@ -59,7 +59,7 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR String accessToken = jwtUtil.createAccessToken(principal, role); String refreshToken = jwtUtil.createRefreshToken(principal, role); - redisUtil.setData("refresh:" + jwtUtil.getPrincipal(refreshToken), refreshToken, Constant.REFRESH_TOKEN_EXPIRATION_TIME); + redisUtil.setData("refresh:" + principal, refreshToken, Constant.REFRESH_TOKEN_EXPIRATION_TIME); setBody(role, response); ResponseCookie accessCookie = createCookie("accessToken", accessToken,"/"); diff --git a/src/main/java/com/pickyfy/pickyfy/auth/filter/JwtAuthFilter.java b/src/main/java/com/pickyfy/pickyfy/auth/filter/JwtAuthFilter.java index c8121a1..7adab87 100644 --- a/src/main/java/com/pickyfy/pickyfy/auth/filter/JwtAuthFilter.java +++ b/src/main/java/com/pickyfy/pickyfy/auth/filter/JwtAuthFilter.java @@ -2,6 +2,7 @@ import com.pickyfy.pickyfy.common.util.JwtUtil; import com.pickyfy.pickyfy.auth.details.CustomUserDetailsServiceImpl; +import com.pickyfy.pickyfy.web.dto.response.TokenValidationResult; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.Cookie; @@ -28,7 +29,14 @@ public class JwtAuthFilter extends OncePerRequestFilter { protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain) throws ServletException, IOException { String token = getAccessTokenFromCookies(request); - if (token == null || !jwtUtil.validateToken(token)) { + if(token == null){ + filterChain.doFilter(request, response); + return; + } + + TokenValidationResult result = jwtUtil.validateTokenWithoutException(token); + if (!result.isValid()) { + request.setAttribute("errorMessage", result.message()); filterChain.doFilter(request, response); return; } diff --git a/src/main/java/com/pickyfy/pickyfy/auth/handler/CustomAuthenticationEntryPoint.java b/src/main/java/com/pickyfy/pickyfy/auth/handler/CustomAuthenticationEntryPoint.java index 8b6db8e..c0db9ad 100644 --- a/src/main/java/com/pickyfy/pickyfy/auth/handler/CustomAuthenticationEntryPoint.java +++ b/src/main/java/com/pickyfy/pickyfy/auth/handler/CustomAuthenticationEntryPoint.java @@ -6,26 +6,35 @@ import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.stereotype.Component; import java.io.IOException; +import java.util.Map; @Component public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { - String message = "인증 정보가 없습니다. 로그인 후 다시 시도하세요"; + String defaultMessage = "인증 정보가 없습니다. 로그인 후 다시 시도하세요"; + String defaultCode = "401"; + + Map errorCodeMapping = Map.of( + "유효하지 않은 토큰입니다.", "4012", + "토큰 만료", "4013" + ); + String message = (request.getAttribute("errorMessage") != null) + ? request.getAttribute("errorMessage").toString() + : defaultMessage; + + String code = errorCodeMapping.getOrDefault(message, defaultCode); - if(request.getAttribute("errorMessage") != null){ - message = request.getAttribute("errorMessage").toString(); - } response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); response.getWriter().write(String.format(""" { "isSuccess": false, - "code": "401", + "code": "%s", "message": "%s" } - """, message)); + """, code, message)); } } \ No newline at end of file diff --git a/src/main/java/com/pickyfy/pickyfy/service/AuthServiceImpl.java b/src/main/java/com/pickyfy/pickyfy/service/AuthServiceImpl.java index fd332a0..fa93bf7 100644 --- a/src/main/java/com/pickyfy/pickyfy/service/AuthServiceImpl.java +++ b/src/main/java/com/pickyfy/pickyfy/service/AuthServiceImpl.java @@ -4,11 +4,8 @@ import com.pickyfy.pickyfy.common.util.JwtUtil; import com.pickyfy.pickyfy.common.util.RedisUtil; import com.pickyfy.pickyfy.exception.ExceptionHandler; -import com.pickyfy.pickyfy.exception.GeneralException; import com.pickyfy.pickyfy.web.apiResponse.error.ErrorStatus; import com.pickyfy.pickyfy.web.dto.response.AuthResponse; -import io.jsonwebtoken.ExpiredJwtException; -import io.jsonwebtoken.JwtException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -26,29 +23,21 @@ public void logout(String refreshToken){ @Override public AuthResponse reIssue(String token){ - try { - validateRefreshToken(token); - String principal = jwtUtil.getPrincipal(token); - String accessToken = jwtUtil.createAccessToken(principal, jwtUtil.getRole(token)); - String refreshToken = jwtUtil.createRefreshToken(principal, jwtUtil.getRole(token)); - - redisUtil.setData("refresh:" + jwtUtil.getPrincipal(refreshToken), refreshToken, Constant.REFRESH_TOKEN_EXPIRATION_TIME); - return AuthResponse.from(accessToken, refreshToken); - } catch (ExpiredJwtException e) { - // 만료된 리프레시 토큰 - throw new GeneralException(ErrorStatus.TOKEN_EXPIRATION); - } catch (JwtException e) { - // 유효하지 않은 리프레시 토큰 - throw new GeneralException(ErrorStatus.TOKEN_INVALID); + validateRefreshToken(token); + String principal = jwtUtil.getPrincipal(token); + String accessToken = jwtUtil.createAccessToken(principal, jwtUtil.getRole(token)); + String refreshToken = jwtUtil.createRefreshToken(principal, jwtUtil.getRole(token)); + + redisUtil.setData("refresh:" + principal, refreshToken, Constant.REFRESH_TOKEN_EXPIRATION_TIME); + return AuthResponse.from(accessToken, refreshToken); } - } @Override public boolean isAuthenticated(String accessToken) { - return jwtUtil.validateToken(accessToken); + return jwtUtil.validateTokenWithoutException(accessToken).isValid(); } - public void validateRefreshToken(String token){ + public void validateRefreshToken(String token) { jwtUtil.validateToken(token); String getToken = redisUtil.getData("refresh:" + jwtUtil.getPrincipal(token)); if(!token.equals(getToken)){