From 34f82bbc795633587b2d3532888d652dbcf835c9 Mon Sep 17 00:00:00 2001 From: tkdwns414 Date: Fri, 12 Jan 2024 06:08:24 +0900 Subject: [PATCH 1/2] [fix] add Transactional to test token provide api --- .../org/pingle/pingleserver/controller/TestController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/pingle/pingleserver/controller/TestController.java b/src/main/java/org/pingle/pingleserver/controller/TestController.java index 3003380..4000608 100644 --- a/src/main/java/org/pingle/pingleserver/controller/TestController.java +++ b/src/main/java/org/pingle/pingleserver/controller/TestController.java @@ -6,11 +6,11 @@ import org.pingle.pingleserver.domain.User; import org.pingle.pingleserver.dto.response.JwtTokenResponse; import org.pingle.pingleserver.exception.CustomException; -import org.pingle.pingleserver.dto.response.JwtTokenResponse; import org.pingle.pingleserver.dto.type.ErrorMessage; import org.pingle.pingleserver.repository.UserRepository; import org.pingle.pingleserver.utils.JwtUtil; import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @@ -25,6 +25,7 @@ public class TestController { private final JwtUtil jwtUtil; private final UserRepository userRepository; + @Transactional @GetMapping("/token/{userId}") public JwtTokenResponse testToken(@PathVariable Long userId) { User user = userRepository.findById(userId) From 521f202ed33500f2bfebac6d86f8cbc543b91f8c Mon Sep 17 00:00:00 2001 From: tkdwns414 Date: Fri, 12 Jan 2024 06:11:02 +0900 Subject: [PATCH 2/2] [fix] change logic to treat token differently by type --- .../controller/AuthController.java | 5 ++--- .../dto/request/ReissueRequest.java | 6 ------ .../pingleserver/dto/type/ErrorMessage.java | 9 ++++---- .../filter/JwtAuthenticationFilter.java | 8 ++++++- .../pingleserver/service/AuthService.java | 21 +++++++++++++++---- 5 files changed, 31 insertions(+), 18 deletions(-) delete mode 100644 src/main/java/org/pingle/pingleserver/dto/request/ReissueRequest.java diff --git a/src/main/java/org/pingle/pingleserver/controller/AuthController.java b/src/main/java/org/pingle/pingleserver/controller/AuthController.java index ba38a64..7af89d3 100644 --- a/src/main/java/org/pingle/pingleserver/controller/AuthController.java +++ b/src/main/java/org/pingle/pingleserver/controller/AuthController.java @@ -7,7 +7,6 @@ import org.pingle.pingleserver.constant.Constants; import org.pingle.pingleserver.dto.common.ApiResponse; import org.pingle.pingleserver.dto.request.LoginRequest; -import org.pingle.pingleserver.dto.request.ReissueRequest; import org.pingle.pingleserver.dto.response.JwtTokenResponse; import org.pingle.pingleserver.dto.type.SuccessMessage; import org.pingle.pingleserver.service.AuthService; @@ -29,8 +28,8 @@ public ApiResponse login( @PostMapping("/reissue") public ApiResponse reissue( - @Valid @RequestBody ReissueRequest request){ - return ApiResponse.success(SuccessMessage.OK, authService.reissue(request)); + @NotNull @RequestHeader(Constants.AUTHORIZATION_HEADER) String refreshToken){ + return ApiResponse.success(SuccessMessage.OK, authService.reissue(refreshToken)); } @PostMapping("/logout") diff --git a/src/main/java/org/pingle/pingleserver/dto/request/ReissueRequest.java b/src/main/java/org/pingle/pingleserver/dto/request/ReissueRequest.java deleted file mode 100644 index 8933b6c..0000000 --- a/src/main/java/org/pingle/pingleserver/dto/request/ReissueRequest.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.pingle.pingleserver.dto.request; - -import jakarta.validation.constraints.NotNull; - -public record ReissueRequest(@NotNull String refreshToken) { -} diff --git a/src/main/java/org/pingle/pingleserver/dto/type/ErrorMessage.java b/src/main/java/org/pingle/pingleserver/dto/type/ErrorMessage.java index 27859ca..282d74c 100644 --- a/src/main/java/org/pingle/pingleserver/dto/type/ErrorMessage.java +++ b/src/main/java/org/pingle/pingleserver/dto/type/ErrorMessage.java @@ -13,10 +13,11 @@ public enum ErrorMessage { EXPIRED_APPLE_IDENTITY_TOKEN(HttpStatus.BAD_REQUEST, "만료된 Apple Identity Token입니다."), CREATE_PUBLIC_KEY_EXCEPTION(HttpStatus.BAD_REQUEST, "Apple Public verify에 실패했습니다."), // JWT Error - INVALID_JWT_TOKEN(HttpStatus.UNAUTHORIZED, "유효하지 않은 JWT 토큰입니다."), - EXPIRED_JWT_TOKEN(HttpStatus.UNAUTHORIZED, "만료된 JWT 토큰입니다."), - UNSUPPORTED_JWT_TOKEN(HttpStatus.UNAUTHORIZED, "지원하지 않는 JWT 토큰입니다."), - JWT_TOKEN_IS_EMPTY(HttpStatus.UNAUTHORIZED, "JWT 토큰이 비어있습니다."), + INVALID_JWT_TOKEN(HttpStatus.UNAUTHORIZED, "유효하지 않은 토큰입니다."), + EXPIRED_JWT_TOKEN(HttpStatus.UNAUTHORIZED, "만료된 토큰입니다."), + UNSUPPORTED_JWT_TOKEN(HttpStatus.UNAUTHORIZED, "지원하지 않는 토큰입니다."), + JWT_TOKEN_IS_EMPTY(HttpStatus.UNAUTHORIZED, "토큰이 비어있습니다."), + INVALID_TOKEN_TYPE(HttpStatus.UNAUTHORIZED, "유효하지 않은 토큰 타입입니다."), // Invalid Argument Error 400 BAD_REQUEST(HttpStatus.BAD_REQUEST, "잘못된 요청입니다."), ALREADY_REGISTERED_USER(HttpStatus.BAD_REQUEST, "이미 가입된 사용자입니다."), diff --git a/src/main/java/org/pingle/pingleserver/security/filter/JwtAuthenticationFilter.java b/src/main/java/org/pingle/pingleserver/security/filter/JwtAuthenticationFilter.java index 5244688..6695d5f 100644 --- a/src/main/java/org/pingle/pingleserver/security/filter/JwtAuthenticationFilter.java +++ b/src/main/java/org/pingle/pingleserver/security/filter/JwtAuthenticationFilter.java @@ -9,6 +9,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.pingle.pingleserver.constant.Constants; +import org.pingle.pingleserver.dto.type.ErrorMessage; +import org.pingle.pingleserver.exception.CustomException; import org.pingle.pingleserver.security.info.UserAuthentication; import org.pingle.pingleserver.utils.JwtUtil; import org.springframework.security.core.context.SecurityContextHolder; @@ -33,7 +35,11 @@ protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull Ht if (StringUtils.hasText(token)) { Claims claims = jwtUtil.getTokenBody(token); - Long userId = claims.get("uid", Long.class); + Long userId = claims.get(Constants.USER_ID_CLAIM_NAME, Long.class); + if (claims.get(Constants.USER_ROLE_CLAIM_NAME, String.class) == null) { + if (!request.getRequestURI().equals("/v1/auth/reissue")) + throw new CustomException(ErrorMessage.INVALID_TOKEN_TYPE); + } UserAuthentication authentication = new UserAuthentication(userId, null, null); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authentication); diff --git a/src/main/java/org/pingle/pingleserver/service/AuthService.java b/src/main/java/org/pingle/pingleserver/service/AuthService.java index cf44234..e524276 100644 --- a/src/main/java/org/pingle/pingleserver/service/AuthService.java +++ b/src/main/java/org/pingle/pingleserver/service/AuthService.java @@ -1,10 +1,11 @@ package org.pingle.pingleserver.service; +import io.jsonwebtoken.Claims; import lombok.RequiredArgsConstructor; +import org.pingle.pingleserver.constant.Constants; import org.pingle.pingleserver.domain.User; import org.pingle.pingleserver.domain.enums.Provider; import org.pingle.pingleserver.domain.enums.URole; -import org.pingle.pingleserver.dto.request.ReissueRequest; import org.pingle.pingleserver.exception.CustomException; import org.pingle.pingleserver.oauth.dto.SocialInfoDto; import org.pingle.pingleserver.dto.request.LoginRequest; @@ -35,9 +36,13 @@ public JwtTokenResponse login(String providerToken, LoginRequest request) { } @Transactional - public JwtTokenResponse reissue(ReissueRequest request) { - jwtUtil.getTokenBody(request.refreshToken()); - User user = userRepository.findByRefreshTokenAndIsDeleted(request.refreshToken(), false) + public JwtTokenResponse reissue(String token) { + String refreshToken = getToken(token); + Claims claims = jwtUtil.getTokenBody(refreshToken); + if (claims.get(Constants.USER_ROLE_CLAIM_NAME, String.class) != null) { + throw new CustomException(ErrorMessage.INVALID_TOKEN_TYPE); + } + User user = userRepository.findByRefreshTokenAndIsDeleted(refreshToken, false) .orElseThrow(() -> new CustomException(ErrorMessage.USER_NOT_FOUND)); return generateTokensWithUpdateRefreshToken(user); } @@ -82,4 +87,12 @@ private JwtTokenResponse generateTokensWithUpdateRefreshToken(User user){ return jwtTokenResponse; } + private String getToken(String token){ + if (token.startsWith(Constants.BEARER_PREFIX)){ + return token.substring(Constants.BEARER_PREFIX.length()); + } else { + return token; + } + } + }