From bf45cff9395937c028b9846b8e22ebb2ca73c3f7 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Fri, 14 Jun 2024 13:24:17 +0900 Subject: [PATCH] =?UTF-8?q?refactor=20:=20refreshToken=20=EB=B9=84?= =?UTF-8?q?=EA=B5=90=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{RedisRepository.java => TokenRepository.java} | 4 +++- .../org/example/security/token/JWTGenerator.java | 7 ++++++- .../security/token/RefreshTokenProcessor.java | 13 +++++++++---- .../example/security/token/JWTGeneratorTest.java | 7 +++++-- .../org/example/security/token/JWTHandlerTest.java | 5 ++++- .../org/example/repository/RedisRepository.java | 9 --------- .../main/java/org/example/service/UserService.java | 8 ++------ app/infrastructure/redis/build.gradle | 1 - .../example/repository/LettuceRedisRepository.java | 8 +++++++- 9 files changed, 36 insertions(+), 26 deletions(-) rename app/api/common-api/src/main/java/org/example/repository/{RedisRepository.java => TokenRepository.java} (64%) delete mode 100644 app/api/user-api/src/main/java/org/example/repository/RedisRepository.java diff --git a/app/api/common-api/src/main/java/org/example/repository/RedisRepository.java b/app/api/common-api/src/main/java/org/example/repository/TokenRepository.java similarity index 64% rename from app/api/common-api/src/main/java/org/example/repository/RedisRepository.java rename to app/api/common-api/src/main/java/org/example/repository/TokenRepository.java index d7d1782b..f98cc5d5 100644 --- a/app/api/common-api/src/main/java/org/example/repository/RedisRepository.java +++ b/app/api/common-api/src/main/java/org/example/repository/TokenRepository.java @@ -3,7 +3,9 @@ import org.springframework.stereotype.Component; @Component -public interface RedisRepository { +public interface TokenRepository { void save(String userId, String refreshToken); + + String getOldRefreshToken(String userId); } diff --git a/app/api/common-api/src/main/java/org/example/security/token/JWTGenerator.java b/app/api/common-api/src/main/java/org/example/security/token/JWTGenerator.java index 0568f166..af6181a1 100644 --- a/app/api/common-api/src/main/java/org/example/security/token/JWTGenerator.java +++ b/app/api/common-api/src/main/java/org/example/security/token/JWTGenerator.java @@ -4,6 +4,7 @@ import java.util.Date; import lombok.RequiredArgsConstructor; import org.example.property.TokenProperty; +import org.example.repository.TokenRepository; import org.example.security.dto.TokenParam; import org.example.security.dto.UserParam; import org.springframework.stereotype.Component; @@ -13,12 +14,16 @@ public class JWTGenerator { private final TokenProperty tokenProperty; + private final TokenRepository tokenRepository; public TokenParam generate(UserParam userParam, Date from) { - return TokenParam.builder() + TokenParam tokenParam = TokenParam.builder() .accessToken(createAccessToken(userParam, from)) .refreshToken(createRefreshToken(userParam, from)) .build(); + + tokenRepository.save(userParam.userId().toString(), tokenParam.refreshToken()); + return tokenParam; } private String createAccessToken(UserParam userParam, Date from) { diff --git a/app/api/common-api/src/main/java/org/example/security/token/RefreshTokenProcessor.java b/app/api/common-api/src/main/java/org/example/security/token/RefreshTokenProcessor.java index 1f275367..8dddca1c 100644 --- a/app/api/common-api/src/main/java/org/example/security/token/RefreshTokenProcessor.java +++ b/app/api/common-api/src/main/java/org/example/security/token/RefreshTokenProcessor.java @@ -3,9 +3,11 @@ import jakarta.servlet.http.HttpServletRequest; import java.util.Date; import lombok.RequiredArgsConstructor; -import org.example.repository.RedisRepository; +import org.example.exception.BusinessException; +import org.example.repository.TokenRepository; import org.example.security.dto.TokenParam; import org.example.security.dto.UserParam; +import org.example.security.vo.TokenError; import org.springframework.stereotype.Component; @Component @@ -14,17 +16,20 @@ public class RefreshTokenProcessor { private final JWTHandler jwtHandler; private final JWTGenerator jwtGenerator; - private final RedisRepository redisRepository; + private final TokenRepository tokenRepository; public TokenParam reissueToken(HttpServletRequest request) { String refreshToken = jwtHandler.extractRefreshToken(request); UserParam userParam = jwtHandler.extractUserFrom(refreshToken); - // 기존 redis의 Refresh토큰과 비교해서 맞는 refresh인지 확인 해야함 + String oldRefreshToken = tokenRepository.getOldRefreshToken(userParam.userId().toString()); + if (!refreshToken.equals(oldRefreshToken)) { + throw new BusinessException(TokenError.INVALID_TOKEN); + } TokenParam newTokenParam = jwtGenerator.generate(userParam, new Date()); - redisRepository.save(userParam.userId().toString(), newTokenParam.refreshToken()); + tokenRepository.save(userParam.userId().toString(), newTokenParam.refreshToken()); return newTokenParam; } } diff --git a/app/api/common-api/src/test/java/org/example/security/token/JWTGeneratorTest.java b/app/api/common-api/src/test/java/org/example/security/token/JWTGeneratorTest.java index f5e1d5b1..7449e925 100644 --- a/app/api/common-api/src/test/java/org/example/security/token/JWTGeneratorTest.java +++ b/app/api/common-api/src/test/java/org/example/security/token/JWTGeneratorTest.java @@ -1,10 +1,13 @@ package org.example.security.token; +import static org.mockito.Mockito.mock; + import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Jwts; import java.util.Date; import java.util.UUID; import org.example.property.TokenProperty; +import org.example.repository.TokenRepository; import org.example.security.dto.TokenParam; import org.example.security.dto.UserParam; import org.example.vo.UserRoleApiType; @@ -23,8 +26,8 @@ class JWTGeneratorTest { hour, twoWeeks ); - - JWTGenerator tokenGenerator = new JWTGenerator(tokenProperty); + TokenRepository tokenRepository = mock(TokenRepository.class); + JWTGenerator tokenGenerator = new JWTGenerator(tokenProperty, tokenRepository); UserParam userParam = new UserParam( UUID.randomUUID(), UserRoleApiType.USER diff --git a/app/api/common-api/src/test/java/org/example/security/token/JWTHandlerTest.java b/app/api/common-api/src/test/java/org/example/security/token/JWTHandlerTest.java index 7227d068..2e43fbe5 100644 --- a/app/api/common-api/src/test/java/org/example/security/token/JWTHandlerTest.java +++ b/app/api/common-api/src/test/java/org/example/security/token/JWTHandlerTest.java @@ -2,11 +2,13 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; import java.util.Date; import java.util.UUID; import org.example.exception.BusinessException; import org.example.property.TokenProperty; +import org.example.repository.TokenRepository; import org.example.security.dto.TokenParam; import org.example.security.dto.UserParam; import org.example.security.vo.TokenError; @@ -22,8 +24,9 @@ class JWTHandlerTest { 3600000L, 1209600000L ); + TokenRepository tokenRepository = mock(TokenRepository.class); JWTHandler jwtHandler = new JWTHandler(tokenProperty); - JWTGenerator jwtGenerator = new JWTGenerator(tokenProperty); + JWTGenerator jwtGenerator = new JWTGenerator(tokenProperty, tokenRepository); UserParam userParam = new UserParam( UUID.randomUUID(), UserRoleApiType.USER diff --git a/app/api/user-api/src/main/java/org/example/repository/RedisRepository.java b/app/api/user-api/src/main/java/org/example/repository/RedisRepository.java deleted file mode 100644 index d7d1782b..00000000 --- a/app/api/user-api/src/main/java/org/example/repository/RedisRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.example.repository; - -import org.springframework.stereotype.Component; - -@Component -public interface RedisRepository { - - void save(String userId, String refreshToken); -} diff --git a/app/api/user-api/src/main/java/org/example/service/UserService.java b/app/api/user-api/src/main/java/org/example/service/UserService.java index abeaef16..9b6ec699 100644 --- a/app/api/user-api/src/main/java/org/example/service/UserService.java +++ b/app/api/user-api/src/main/java/org/example/service/UserService.java @@ -3,7 +3,6 @@ import java.util.Date; import lombok.RequiredArgsConstructor; import org.example.entity.User; -import org.example.repository.RedisRepository; import org.example.security.dto.TokenParam; import org.example.security.dto.UserParam; import org.example.security.token.JWTGenerator; @@ -18,7 +17,7 @@ public class UserService { private final UserUseCase userUseCase; private final JWTGenerator jwtGenerator; - private final RedisRepository redisRepository; + public TokenParam login(final LoginServiceRequest loginServiceRequest) { User createdUser = userUseCase.save(loginServiceRequest.toLoginServiceDto().toUser()); @@ -26,11 +25,8 @@ public TokenParam login(final LoginServiceRequest loginServiceRequest) { .userId(createdUser.getId()) .role(UserRoleApiType.valueOf(createdUser.getUserRole().name())) .build(); - TokenParam tokenParam = jwtGenerator.generate(userParam, new Date()); - - redisRepository.save(userParam.userId().toString(), tokenParam.refreshToken()); - return tokenParam; + return jwtGenerator.generate(userParam, new Date()); } public String findNickname(final User user) { diff --git a/app/infrastructure/redis/build.gradle b/app/infrastructure/redis/build.gradle index cc56c6b0..f901e61e 100644 --- a/app/infrastructure/redis/build.gradle +++ b/app/infrastructure/redis/build.gradle @@ -2,7 +2,6 @@ bootJar.enabled = false jar.enabled = true dependencies { - implementation project(":app:api:user-api") implementation project(":app:api:common-api") //redis diff --git a/app/infrastructure/redis/src/main/java/org/example/repository/LettuceRedisRepository.java b/app/infrastructure/redis/src/main/java/org/example/repository/LettuceRedisRepository.java index 5d22c252..d861b84d 100644 --- a/app/infrastructure/redis/src/main/java/org/example/repository/LettuceRedisRepository.java +++ b/app/infrastructure/redis/src/main/java/org/example/repository/LettuceRedisRepository.java @@ -7,12 +7,18 @@ @Component @RequiredArgsConstructor -public class LettuceRedisRepository implements RedisRepository { +public class LettuceRedisRepository implements TokenRepository { private final StringRedisTemplate stringRedisTemplate; + @Override public void save(String userId, String refreshToken) { stringRedisTemplate.opsForValue().set("userId:" + userId, refreshToken, 14, TimeUnit.DAYS); } + @Override + public String getOldRefreshToken(String userId) { + return stringRedisTemplate.opsForValue().get("userId:" + userId); + } + }