diff --git a/src/main/java/com/recipe/app/src/common/config/JwtFilter.java b/src/main/java/com/recipe/app/src/common/config/JwtFilter.java index 11762324..427db954 100644 --- a/src/main/java/com/recipe/app/src/common/config/JwtFilter.java +++ b/src/main/java/com/recipe/app/src/common/config/JwtFilter.java @@ -35,10 +35,14 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha if (!StringUtils.hasText(accessToken)) { logger.info("필수 토큰이 없습니다., uri: {}", requestURI); } else if (jwtUtil.isValidAccessToken(accessToken)) { - UserDetails userDetails = userDetailsService.loadUserByUsername(String.valueOf(jwtUtil.getUserId(accessToken))); - Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities()); - SecurityContextHolder.getContext().setAuthentication(authentication); - logger.info("Security context에 인증 정보를 저장했습니다, uri: {}", requestURI); + try { + UserDetails userDetails = userDetailsService.loadUserByUsername(String.valueOf(jwtUtil.getUserId(accessToken))); + Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(authentication); + logger.info("Security context에 인증 정보를 저장했습니다, uri: {}", requestURI); + } catch (Exception e) { + logger.info("사용자 인증에 실패했습니다. {}, uri: {}", e.getMessage(), requestURI); + } } else { logger.info("유효한 Jwt 토큰이 없습니다, uri: {}", requestURI); } diff --git a/src/main/java/com/recipe/app/src/user/application/CustomUserDetailsService.java b/src/main/java/com/recipe/app/src/user/application/CustomUserDetailsService.java index 7c4d787d..2c37ea8b 100644 --- a/src/main/java/com/recipe/app/src/user/application/CustomUserDetailsService.java +++ b/src/main/java/com/recipe/app/src/user/application/CustomUserDetailsService.java @@ -1,6 +1,7 @@ package com.recipe.app.src.user.application; import com.recipe.app.src.user.domain.SecurityUser; +import com.recipe.app.src.user.domain.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; @@ -20,6 +21,13 @@ public CustomUserDetailsService(UserService userService) { @Transactional(readOnly = true) @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - return new SecurityUser(userService.findByUserId(Long.parseLong(username))); + + User user = userService.findByUserId(Long.parseLong(username)); + + if (user.isDeleted()) { + throw new UsernameNotFoundException("탈퇴한 사용자입니다."); + } + + return new SecurityUser(user); } } diff --git a/src/main/java/com/recipe/app/src/user/application/UserService.java b/src/main/java/com/recipe/app/src/user/application/UserService.java index 0f4c2c4e..4df4cbaf 100644 --- a/src/main/java/com/recipe/app/src/user/application/UserService.java +++ b/src/main/java/com/recipe/app/src/user/application/UserService.java @@ -171,6 +171,11 @@ public UserTokenRefreshResponse reissueToken(UserTokenRefreshRequest request) { throw new UserTokenNotExistException(); } + User user = findByUserId(request.getUserId()); + if (user.isDeleted()) { + throw new UserTokenNotExistException(); + } + return UserTokenRefreshResponse.builder() .userId(request.getUserId()) .accessToken(jwtUtil.createAccessToken(request.getUserId())) diff --git a/src/main/java/com/recipe/app/src/user/domain/UserWithdrawal.java b/src/main/java/com/recipe/app/src/user/domain/UserWithdrawal.java index 90c59c91..ae879c52 100644 --- a/src/main/java/com/recipe/app/src/user/domain/UserWithdrawal.java +++ b/src/main/java/com/recipe/app/src/user/domain/UserWithdrawal.java @@ -27,7 +27,7 @@ public class UserWithdrawal { @Column(name = "userId", nullable = false) private Long userId; - @Column(name = "withdrawalReason", length = 200) + @Column(name = "withdrawalReason") private String withdrawalReason; @Column(name = "createdAt", nullable = false, updatable = false) diff --git a/src/test/groovy/com/recipe/app/src/user/application/UserServiceTest.groovy b/src/test/groovy/com/recipe/app/src/user/application/UserServiceTest.groovy index fc89fa67..44a25b10 100644 --- a/src/test/groovy/com/recipe/app/src/user/application/UserServiceTest.groovy +++ b/src/test/groovy/com/recipe/app/src/user/application/UserServiceTest.groovy @@ -420,12 +420,19 @@ class UserServiceTest extends Specification { def "토큰 재발급"() { given: + User user = User.builder() + .userId(1) + .socialId("naver_1") + .nickname("테스터1") + .build() + UserTokenRefreshRequest request = UserTokenRefreshRequest.builder() .userId(1) .refreshToken("refresh_token") .build() jwtUtil.isValidRefreshToken(request.refreshToken) >> true + userRepository.findById(request.userId) >> Optional.of(user) String accessToken = "new_access_token" String refreshToken = "new_refresh_token" @@ -458,4 +465,30 @@ class UserServiceTest extends Specification { def e = thrown(UserTokenNotExistException.class) e.message == "유효하지 않은 JWT입니다." } + + def "토큰 재발급 시 탈퇴한 사용자이면 예외 발생"() { + + given: + User user = User.builder() + .userId(1) + .socialId("naver_1") + .nickname("테스터1") + .build() + user.markAsDeleted() + + UserTokenRefreshRequest request = UserTokenRefreshRequest.builder() + .userId(1) + .refreshToken("refresh_token") + .build() + + jwtUtil.isValidRefreshToken(request.refreshToken) >> true + userRepository.findById(request.userId) >> Optional.of(user) + + when: + userService.reissueToken(request) + + then: + def e = thrown(UserTokenNotExistException.class) + e.message == "유효하지 않은 JWT입니다." + } }