From 0f091ff7f619e1242f824dba810e67b3d42a7e13 Mon Sep 17 00:00:00 2001 From: nYeonG4001 <2371324@hansung.ac.kr> Date: Sun, 12 Apr 2026 14:22:47 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20Refresh=20Token=20rotation=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=EB=A1=9C=20=EB=8F=99=EC=8B=9C=20=EC=9E=AC=EB=B0=9C?= =?UTF-8?q?=EA=B8=89=20=EB=A0=88=EC=9D=B4=EC=8A=A4=20=EC=BB=A8=EB=94=94?= =?UTF-8?q?=EC=85=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devpick/domain/user/service/TokenService.java | 13 ++----------- .../domain/user/service/TokenServiceTest.java | 12 ++++-------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/devpick/domain/user/service/TokenService.java b/src/main/java/com/devpick/domain/user/service/TokenService.java index b2788c2..11b0d6e 100644 --- a/src/main/java/com/devpick/domain/user/service/TokenService.java +++ b/src/main/java/com/devpick/domain/user/service/TokenService.java @@ -91,19 +91,10 @@ public String[] reissueTokens(String refreshToken) { User user = stored.getUser(); - // 4. 기존 토큰 삭제 + 신규 토큰 발급 (Token Rotation) - refreshTokenRepository.deleteByUser(user); - + // 4. Access Token만 새로 발급, Refresh Token은 유지 (레이스 컨디션 방지) String newAccessToken = jwtTokenProvider.generateAccessToken(user.getId()); - String newRefreshToken = jwtTokenProvider.generateRefreshToken(); - - refreshTokenRepository.save(RefreshToken.builder() - .user(user) - .token(newRefreshToken) - .expiresAt(jwtTokenProvider.getRefreshTokenExpiresAt()) - .build()); - return new String[]{newAccessToken, newRefreshToken}; + return new String[]{newAccessToken, refreshToken}; } /** diff --git a/src/test/java/com/devpick/domain/user/service/TokenServiceTest.java b/src/test/java/com/devpick/domain/user/service/TokenServiceTest.java index e659acc..25624bf 100644 --- a/src/test/java/com/devpick/domain/user/service/TokenServiceTest.java +++ b/src/test/java/com/devpick/domain/user/service/TokenServiceTest.java @@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @ExtendWith(MockitoExtension.class) @@ -84,18 +85,13 @@ void reissueTokens_success() throws Exception { .willReturn(Optional.of(stored)); given(jwtTokenProvider.generateAccessToken(user.getId())) .willReturn("new-access-token"); - given(jwtTokenProvider.generateRefreshToken()) - .willReturn("new-refresh-token"); - given(jwtTokenProvider.getRefreshTokenExpiresAt()) - .willReturn(LocalDateTime.now().plusDays(7)); - given(refreshTokenRepository.save(any(RefreshToken.class))) - .willAnswer(invocation -> invocation.getArgument(0)); String[] tokens = tokenService.reissueTokens("old-refresh-token"); assertThat(tokens[0]).isEqualTo("new-access-token"); - assertThat(tokens[1]).isEqualTo("new-refresh-token"); - verify(refreshTokenRepository).deleteByUser(user); + assertThat(tokens[1]).isEqualTo("old-refresh-token"); + verify(refreshTokenRepository, never()).deleteByUser(any()); + verify(refreshTokenRepository, never()).save(any()); } @Test