From 8d522e09bf9f8cd34b89444f09979586ba12f373 Mon Sep 17 00:00:00 2001 From: sakjung Date: Tue, 14 Mar 2023 23:47:40 +0900 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20jwtUtils=20getPayload=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EB=82=B4=EB=B6=80=EC=97=90=20try=20catch?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EB=84=A3=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit zzimkkong exception 으로 wrapping 해서 401 나도록 수정 --- .../zzimkkong/infrastructure/auth/JwtUtils.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/infrastructure/auth/JwtUtils.java b/backend/src/main/java/com/woowacourse/zzimkkong/infrastructure/auth/JwtUtils.java index 6c03e5d33..0f208e3e4 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/infrastructure/auth/JwtUtils.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/infrastructure/auth/JwtUtils.java @@ -48,7 +48,13 @@ public void validateToken(String token) { } public String getPayload(String token) { - return jwtParser.parseClaimsJws(token).getBody().getSubject(); + try { + return jwtParser.parseClaimsJws(token).getBody().getSubject(); + } catch (ExpiredJwtException e) { + throw new TokenExpiredException(); + } catch (JwtException e) { + throw new InvalidTokenException(); + } } public static PayloadBuilder payloadBuilder() { From 13c80f16d7b2a7d2a2e32ed00596c9367435fe5d Mon Sep 17 00:00:00 2001 From: sakjung Date: Wed, 15 Mar 2023 00:10:33 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20controller=20advice=20logging=20&?= =?UTF-8?q?=20error=20response=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ControllerAdvice.java | 51 ++++++++----------- .../zzimkkong/dto/ErrorResponse.java | 5 ++ .../zzimkkong/dto/ValidatorMessage.java | 2 +- 3 files changed, 27 insertions(+), 31 deletions(-) diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/controller/ControllerAdvice.java b/backend/src/main/java/com/woowacourse/zzimkkong/controller/ControllerAdvice.java index ef7896049..15ef99d1a 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/controller/ControllerAdvice.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/controller/ControllerAdvice.java @@ -33,12 +33,12 @@ @Slf4j @RestControllerAdvice public class ControllerAdvice implements RequestRejectedHandler { - private static final String MESSAGE_FORMAT = "{} (traceId: {})"; + private static final String MESSAGE_FORMAT = "%s (traceId: %s)"; private static final String TRACE_ID_KEY = "traceId"; @ExceptionHandler(NoSuchOAuthMemberException.class) public ResponseEntity oAuthLoginFailHandler(final NoSuchOAuthMemberException exception) { - logInfo(exception.getMessage()); + logInfo(exception); return ResponseEntity .status(exception.getStatus()) .body(OAuthLoginFailErrorResponse.from(exception)); @@ -46,7 +46,7 @@ public ResponseEntity oAuthLoginFailHandler(final N @ExceptionHandler(InputFieldException.class) public ResponseEntity inputFieldExceptionHandler(final InputFieldException exception) { - logInfo(exception.getMessage()); + logInfo(exception); return ResponseEntity .status(exception.getStatus()) .body(InputFieldErrorResponse.from(exception)); @@ -54,7 +54,7 @@ public ResponseEntity inputFieldExceptionHandler(final @ExceptionHandler(InfrastructureMalfunctionException.class) public ResponseEntity wrongConfigurationOfInfrastructureException(final InfrastructureMalfunctionException exception) { - logWarn(exception.getMessage(), exception); + logWarn(exception); return ResponseEntity .status(exception.getStatus()) .body(ErrorResponse.from(exception)); @@ -62,7 +62,7 @@ public ResponseEntity wrongConfigurationOfInfrastructureException @ExceptionHandler(ZzimkkongException.class) public ResponseEntity zzimkkongExceptionHandler(final ZzimkkongException exception) { - logInfo(exception.getMessage()); + logInfo(exception); return ResponseEntity .status(exception.getStatus()) .body(ErrorResponse.from(exception)); @@ -70,51 +70,42 @@ public ResponseEntity zzimkkongExceptionHandler(final ZzimkkongEx @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity invalidArgumentHandler(final MethodArgumentNotValidException exception) { - logInfo(exception.getMessage()); + logInfo(exception); return ResponseEntity.badRequest().body(InputFieldErrorResponse.from(exception)); } @ExceptionHandler(ConstraintViolationException.class) public ResponseEntity invalidParamHandler(final ConstraintViolationException exception) { - logInfo(exception.getMessage()); + logInfo(exception); return ResponseEntity.badRequest().body(ErrorResponse.from(exception)); } @ExceptionHandler({InvalidFormatException.class, HttpMessageNotReadableException.class}) - public ResponseEntity invalidFormatHandler() { - logInfo(FORMAT_MESSAGE); + public ResponseEntity invalidFormatHandler(final Exception exception) { + logInfo(exception); return ResponseEntity.badRequest().body(ErrorResponse.invalidFormat()); } @ExceptionHandler(DataAccessException.class) - public ResponseEntity invalidDataAccessHandler(final DataAccessException exception) { - logWarn(SERVER_ERROR_MESSAGE, exception); - return ResponseEntity.internalServerError().build(); + public ResponseEntity invalidDataAccessHandler(final DataAccessException exception) { + logWarn(exception); + return ResponseEntity.internalServerError().body(ErrorResponse.internalServerError()); } @ExceptionHandler(Exception.class) - public ResponseEntity unhandledExceptionHandler(final Exception exception) { - logWarn(exception.getMessage(), exception); - return ResponseEntity.internalServerError().build(); + public ResponseEntity unhandledExceptionHandler(final Exception exception) { + logWarn(exception); + return ResponseEntity.internalServerError().body(ErrorResponse.internalServerError()); } - private void logInfo(String message) { - log.info(MESSAGE_FORMAT, - message, - value(TRACE_ID_KEY, getTraceId())); + private void logInfo(Exception exception) { + String logMessage = String.format(MESSAGE_FORMAT, exception.getMessage(), value(TRACE_ID_KEY, getTraceId())); + log.info(logMessage, exception); } - private void logWarn(String message, Exception exception) { - StringWriter stringWriter = new StringWriter(); - PrintWriter printWriter = new PrintWriter(stringWriter); - - exception.printStackTrace(printWriter); - String stackTrace = stringWriter.toString(); - - log.warn(MESSAGE_FORMAT, - message, - value(TRACE_ID_KEY, getTraceId()), - value("stack_trace", stackTrace)); + private void logWarn(Exception exception) { + String logMessage = String.format(MESSAGE_FORMAT, exception.getMessage(), value(TRACE_ID_KEY, getTraceId())); + log.warn(logMessage, exception); } private Object getTraceId() { diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/ErrorResponse.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/ErrorResponse.java index c2a9b00ce..7682e8267 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/ErrorResponse.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/ErrorResponse.java @@ -6,6 +6,7 @@ import javax.validation.ConstraintViolationException; import static com.woowacourse.zzimkkong.dto.ValidatorMessage.FORMAT_MESSAGE; +import static com.woowacourse.zzimkkong.dto.ValidatorMessage.SERVER_ERROR_MESSAGE; @Getter @NoArgsConstructor @@ -28,4 +29,8 @@ public static ErrorResponse from(final ConstraintViolationException exception) { public static ErrorResponse invalidFormat() { return new ErrorResponse(FORMAT_MESSAGE); } + + public static ErrorResponse internalServerError() { + return new ErrorResponse(SERVER_ERROR_MESSAGE); + } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/ValidatorMessage.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/ValidatorMessage.java index 731bb176e..1598d78d0 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/ValidatorMessage.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/ValidatorMessage.java @@ -15,7 +15,7 @@ private ValidatorMessage() { public static final String NOTICE_MESSAGE = "공지사항은 100자 이내로 작성 가능합니다."; public static final String FORMAT_MESSAGE = "날짜 및 시간 데이터 형식이 올바르지 않습니다."; public static final String DAY_OF_WEEK_MESSAGE = "올바른 요일 형식이 아닙니다."; - public static final String SERVER_ERROR_MESSAGE = "예상치 못한 문제가 발생했습니다. 개발자에게 문의하세요."; + public static final String SERVER_ERROR_MESSAGE = "일시적으로 접속이 원활하지 않습니다. 잠시 후 다시 이용해 주시기 바랍니다."; public static final String TIME_UNIT_MESSAGE = "시간 단위는 10, 30, 60, 120입니다."; public static final String SETTING_COUNT_MESSAGE = "공간의 예약 조건이 최소 1개는 존재해야 합니다."; From 41f35901beca4c81aedfd1f10254241e1f57997e Mon Sep 17 00:00:00 2001 From: sakjung Date: Wed, 15 Mar 2023 00:23:03 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20RequestParam=20=EC=97=90=20?= =?UTF-8?q?=EC=9E=98=EB=AA=BB=EB=90=9C=20=ED=8F=AC=EB=A7=B7=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=99=80=EC=84=9C=20TypeMismatch=20=EB=82=A0=20?= =?UTF-8?q?=EB=95=8C,=20400=20=EC=B2=98=EB=A6=AC=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/woowacourse/zzimkkong/controller/ControllerAdvice.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/controller/ControllerAdvice.java b/backend/src/main/java/com/woowacourse/zzimkkong/controller/ControllerAdvice.java index 15ef99d1a..6a9edd3ce 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/controller/ControllerAdvice.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/controller/ControllerAdvice.java @@ -18,6 +18,7 @@ import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -80,7 +81,7 @@ public ResponseEntity invalidParamHandler(final ConstraintViolati return ResponseEntity.badRequest().body(ErrorResponse.from(exception)); } - @ExceptionHandler({InvalidFormatException.class, HttpMessageNotReadableException.class}) + @ExceptionHandler({InvalidFormatException.class, HttpMessageNotReadableException.class, MethodArgumentTypeMismatchException.class}) public ResponseEntity invalidFormatHandler(final Exception exception) { logInfo(exception); return ResponseEntity.badRequest().body(ErrorResponse.invalidFormat()); From 178ad8d979a19fe26cba394fd868cfe7fa218c8d Mon Sep 17 00:00:00 2001 From: sakjung Date: Wed, 15 Mar 2023 10:28:18 +0900 Subject: [PATCH 4/4] =?UTF-8?q?chore:=20token=20=EB=A7=8C=EB=A3=8C?= =?UTF-8?q?=EC=8B=9C=20=EB=82=98=EA=B0=80=EB=8A=94=20=EB=A9=94=EC=84=B8?= =?UTF-8?q?=EC=A7=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/authorization/TokenExpiredException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/exception/authorization/TokenExpiredException.java b/backend/src/main/java/com/woowacourse/zzimkkong/exception/authorization/TokenExpiredException.java index 1df1010cf..d169dbe50 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/exception/authorization/TokenExpiredException.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/exception/authorization/TokenExpiredException.java @@ -4,7 +4,7 @@ import org.springframework.http.HttpStatus; public class TokenExpiredException extends ZzimkkongException { - private static final String MESSAGE = "로그인이 필요한 서비스입니다."; + private static final String MESSAGE = "로그인 인증 유효기간이 만료되었습니다. 다시 로그인 해주세요."; public TokenExpiredException() { super(MESSAGE, HttpStatus.UNAUTHORIZED);