From ac36f55a901f19c4ee4935d5a2cff64dad4edca2 Mon Sep 17 00:00:00 2001 From: seungin Date: Mon, 18 Aug 2025 03:06:48 +0900 Subject: [PATCH 1/6] =?UTF-8?q?[test]=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=BD=94=EB=93=9C=EC=97=90=EC=84=9C=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=EC=8B=9C=20=EB=A6=AC=EB=B7=B0=20=EC=B9=B4?= =?UTF-8?q?=EC=9A=B4=ED=8A=B8=20=EC=A6=9D=EA=B0=80=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wayble/server/review/service/ReviewServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/wayble/server/review/service/ReviewServiceTest.java b/src/test/java/com/wayble/server/review/service/ReviewServiceTest.java index 41fd9b8..b652631 100644 --- a/src/test/java/com/wayble/server/review/service/ReviewServiceTest.java +++ b/src/test/java/com/wayble/server/review/service/ReviewServiceTest.java @@ -66,7 +66,7 @@ void t1() { assertEquals(4.5, ratingCaptor.getValue(), 1e-6); - verify(zone, times(1)).addReviewCount(1L); + verify(zone, times(1)).addReviewCount(1); verify(reviewImageRepository, times(1)).save(any(ReviewImage.class)); verify(waybleZoneRepository, times(1)).save(zone); } From ce61e362bb69a57a0f6c6f641fe5e8b74809d44c Mon Sep 17 00:00:00 2001 From: seungin Date: Tue, 19 Aug 2025 10:23:02 +0900 Subject: [PATCH 2/6] =?UTF-8?q?[refactor]=20=EB=A6=AC=EC=A1=B8=EB=B2=84?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=ED=86=A0=ED=81=B0=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EA=BA=BC=EB=82=B4=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resolver/CurrentUserArgumentResolver.java | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/wayble/server/auth/resolver/CurrentUserArgumentResolver.java b/src/main/java/com/wayble/server/auth/resolver/CurrentUserArgumentResolver.java index 091bad7..72f2727 100644 --- a/src/main/java/com/wayble/server/auth/resolver/CurrentUserArgumentResolver.java +++ b/src/main/java/com/wayble/server/auth/resolver/CurrentUserArgumentResolver.java @@ -1,17 +1,24 @@ package com.wayble.server.auth.resolver; +import com.wayble.server.common.config.security.jwt.JwtTokenProvider; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; import org.springframework.core.MethodParameter; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; @Component +@RequiredArgsConstructor public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver { + private final JwtTokenProvider jwtTokenProvider; + @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.hasParameterAnnotation(CurrentUser.class) @@ -19,27 +26,34 @@ public boolean supportsParameter(MethodParameter parameter) { } @Override - public Object resolveArgument(MethodParameter parameter, - ModelAndViewContainer mav, - NativeWebRequest webRequest, - WebDataBinderFactory binderFactory) { + public Object resolveArgument( + MethodParameter parameter, + ModelAndViewContainer mav, + NativeWebRequest webRequest, + WebDataBinderFactory binderFactory + ) { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - if (auth == null) { - throw new IllegalStateException("인증 정보가 없습니다."); - } - - Object principal = auth.getPrincipal(); - if (principal instanceof Long l) return l; - if (principal instanceof Integer i) return i.longValue(); - if (principal instanceof String s) { - try { + if (auth != null) { + Object principal = auth.getPrincipal(); + if (principal instanceof Long l) { return l; } + if (principal instanceof Integer i) { return i.longValue(); } + if (principal instanceof String s && s.chars().allMatch(Character::isDigit)) { return Long.parseLong(s); - } catch (NumberFormatException ignored) {} + } + String name = auth.getName(); + if (name != null && name.chars().allMatch(Character::isDigit)) { + return Long.parseLong(name); + } } - try { - return Long.parseLong(auth.getName()); - } catch (Exception e) { - throw new IllegalStateException("userId를 추출할 수 없습니다.", e); + + HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); + String authz = request != null ? request.getHeader("Authorization") : null; + if (StringUtils.hasText(authz) && authz.startsWith("Bearer ")) { + String token = authz.substring(7); + Long userId = jwtTokenProvider.getUserId(token); + if (userId != null) { return userId; } } + + throw new IllegalStateException("인증 정보가 없거나 userId를 추출할 수 없습니다."); } } \ No newline at end of file From b44069f278f120a25d4afadc9c19d82bd1a9a6e2 Mon Sep 17 00:00:00 2001 From: seungin Date: Tue, 19 Aug 2025 10:40:52 +0900 Subject: [PATCH 3/6] =?UTF-8?q?[refactor]=20swagger=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=ED=95=84=EC=88=98=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20use?= =?UTF-8?q?rId=20=EC=9E=85=EB=A0=A5=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/review/controller/ReviewController.java | 4 ++-- .../server/user/controller/UserPlaceController.java | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/wayble/server/review/controller/ReviewController.java b/src/main/java/com/wayble/server/review/controller/ReviewController.java index 1661a7c..840b780 100644 --- a/src/main/java/com/wayble/server/review/controller/ReviewController.java +++ b/src/main/java/com/wayble/server/review/controller/ReviewController.java @@ -13,7 +13,7 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; - +import io.swagger.v3.oas.annotations.Parameter; import java.util.List; @@ -37,7 +37,7 @@ public class ReviewController { }) public CommonResponse registerReview( @PathVariable Long waybleZoneId, - @CurrentUser Long userId, + @Parameter(hidden = true) @CurrentUser Long userId, @RequestBody @Valid ReviewRegisterDto dto ) { reviewService.registerReview(waybleZoneId, userId, dto); diff --git a/src/main/java/com/wayble/server/user/controller/UserPlaceController.java b/src/main/java/com/wayble/server/user/controller/UserPlaceController.java index 5dc568a..8401614 100644 --- a/src/main/java/com/wayble/server/user/controller/UserPlaceController.java +++ b/src/main/java/com/wayble/server/user/controller/UserPlaceController.java @@ -9,6 +9,7 @@ import com.wayble.server.user.service.UserPlaceService; import com.wayble.server.wayblezone.dto.WaybleZoneListResponseDto; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import jakarta.validation.Valid; @@ -34,7 +35,7 @@ public class UserPlaceController { @ApiResponse(responseCode = "403", description = "권한이 없습니다.") }) public CommonResponse saveUserPlace( - @CurrentUser Long userId, + @Parameter(hidden = true) @CurrentUser Long userId, @RequestBody @Valid UserPlaceRequestDto request ) { userPlaceService.saveUserPlace(userId, request); // userId 파라미터로 넘김 @@ -49,7 +50,7 @@ public CommonResponse saveUserPlace( @ApiResponse(responseCode = "403", description = "권한이 없습니다.") }) public CommonResponse> getMyPlaceSummaries( - @CurrentUser Long userId, + @Parameter(hidden = true) @CurrentUser Long userId, @RequestParam(name = "sort", defaultValue = "latest") String sort ) { List summaries = userPlaceService.getMyPlaceSummaries(userId, sort); @@ -66,7 +67,7 @@ public CommonResponse> getMyPlaceSummaries( @ApiResponse(responseCode = "403", description = "권한이 없습니다.") }) public CommonResponse> getZonesInPlace( - @CurrentUser Long userId, + @Parameter(hidden = true) @CurrentUser Long userId, @RequestParam Long placeId, @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "20") Integer size @@ -86,7 +87,7 @@ public CommonResponse> getZonesInPlace( @ApiResponse(responseCode = "403", description = "권한이 없습니다.") }) public CommonResponse removeZoneFromPlace( - @CurrentUser Long userId, + @Parameter(hidden = true) @CurrentUser Long userId, @RequestBody @Valid UserPlaceRemoveRequestDto request ) { userPlaceService.removeZoneFromPlace(userId, request.placeId(), request.waybleZoneId()); From 47b3255d3e302ef59e842ff45833302de4234573 Mon Sep 17 00:00:00 2001 From: seungin Date: Tue, 19 Aug 2025 11:08:57 +0900 Subject: [PATCH 4/6] =?UTF-8?q?[feat]=20Auth=20(=EB=A6=AC=EC=A1=B8?= =?UTF-8?q?=EB=B2=84)=20=EA=B4=80=EB=A0=A8=20=EC=97=90=EB=9F=AC=EC=BC=80?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/auth/exception/AuthErrorCase.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/com/wayble/server/auth/exception/AuthErrorCase.java diff --git a/src/main/java/com/wayble/server/auth/exception/AuthErrorCase.java b/src/main/java/com/wayble/server/auth/exception/AuthErrorCase.java new file mode 100644 index 0000000..ae589b4 --- /dev/null +++ b/src/main/java/com/wayble/server/auth/exception/AuthErrorCase.java @@ -0,0 +1,15 @@ +package com.wayble.server.auth.exception; + +import com.wayble.server.common.exception.ErrorCase; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum AuthErrorCase implements ErrorCase { + UNAUTHORIZED(401, 1001, "인증 정보가 없거나 userId를 추출할 수 없습니다."); + + private final Integer httpStatusCode; + private final Integer errorCode; + private final String message; +} From 3faefa3c0f03e3c3a3fffd8cf1f2797cf818a070 Mon Sep 17 00:00:00 2001 From: seungin Date: Tue, 19 Aug 2025 11:10:45 +0900 Subject: [PATCH 5/6] =?UTF-8?q?[refactor]=20=EB=A6=AC=EC=A1=B8=EB=B2=84=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/auth/resolver/CurrentUserArgumentResolver.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/wayble/server/auth/resolver/CurrentUserArgumentResolver.java b/src/main/java/com/wayble/server/auth/resolver/CurrentUserArgumentResolver.java index 72f2727..f38d5bc 100644 --- a/src/main/java/com/wayble/server/auth/resolver/CurrentUserArgumentResolver.java +++ b/src/main/java/com/wayble/server/auth/resolver/CurrentUserArgumentResolver.java @@ -1,6 +1,8 @@ package com.wayble.server.auth.resolver; +import com.wayble.server.auth.exception.AuthErrorCase; import com.wayble.server.common.config.security.jwt.JwtTokenProvider; +import com.wayble.server.common.exception.ApplicationException; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.core.MethodParameter; @@ -54,6 +56,6 @@ public Object resolveArgument( if (userId != null) { return userId; } } - throw new IllegalStateException("인증 정보가 없거나 userId를 추출할 수 없습니다."); + throw new ApplicationException(AuthErrorCase.UNAUTHORIZED); } } \ No newline at end of file From 67a5faadbe9481ca01bb7b36fcdbf248a9bc916e Mon Sep 17 00:00:00 2001 From: seungin Date: Tue, 19 Aug 2025 11:22:16 +0900 Subject: [PATCH 6/6] =?UTF-8?q?[refactor]=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/auth/resolver/CurrentUserArgumentResolver.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/wayble/server/auth/resolver/CurrentUserArgumentResolver.java b/src/main/java/com/wayble/server/auth/resolver/CurrentUserArgumentResolver.java index f38d5bc..cdb7e40 100644 --- a/src/main/java/com/wayble/server/auth/resolver/CurrentUserArgumentResolver.java +++ b/src/main/java/com/wayble/server/auth/resolver/CurrentUserArgumentResolver.java @@ -52,8 +52,12 @@ public Object resolveArgument( String authz = request != null ? request.getHeader("Authorization") : null; if (StringUtils.hasText(authz) && authz.startsWith("Bearer ")) { String token = authz.substring(7); - Long userId = jwtTokenProvider.getUserId(token); - if (userId != null) { return userId; } + try { + Long userId = jwtTokenProvider.getUserId(token); + if (userId != null) { return userId; } + } catch (IllegalArgumentException e) { + throw new ApplicationException(AuthErrorCase.UNAUTHORIZED); + } } throw new ApplicationException(AuthErrorCase.UNAUTHORIZED);