Skip to content

Commit d8116b9

Browse files
committed
feat : 리프레시 토큰 핵심 서비스 작성
1 parent d6919b3 commit d8116b9

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

src/main/java/com/back/domain/auth/refreshToken/repository/RefreshTokenRepository.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
import org.springframework.data.repository.CrudRepository;
55
import org.springframework.stereotype.Repository;
66

7+
import java.util.Optional;
8+
79
@Repository
810
public interface RefreshTokenRepository extends CrudRepository<RefreshToken, String> {
11+
12+
Optional<RefreshToken> findByToken(String token);
13+
14+
void deleteByToken(String token);
915
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.back.domain.auth.refreshToken.service;
2+
3+
import com.back.domain.auth.refreshToken.entity.RefreshToken;
4+
import com.back.domain.auth.refreshToken.repository.RefreshTokenRepository;
5+
import lombok.RequiredArgsConstructor;
6+
import org.springframework.beans.factory.annotation.Value;
7+
import org.springframework.stereotype.Service;
8+
9+
import java.security.SecureRandom;
10+
import java.util.Base64;
11+
import java.util.Optional;
12+
13+
@Service
14+
@RequiredArgsConstructor
15+
public class RefreshTokenService {
16+
17+
private final RefreshTokenRepository refreshTokenRepository;
18+
private final SecureRandom secureRandom = new SecureRandom();
19+
20+
@Value("${custom.refreshToken.expirationSeconds}")
21+
private long refreshTokenExpiration;
22+
23+
// 기존 리프레시 토큰 삭제하고 생성
24+
public String generateRefreshToken(Long userId, String email) {
25+
String token = generateSecureToken();
26+
RefreshToken refreshToken = RefreshToken.create(token, userId, email, refreshTokenExpiration);
27+
refreshTokenRepository.save(refreshToken);
28+
29+
return token;
30+
}
31+
32+
//검증
33+
public boolean validateToken(String token) {
34+
return refreshTokenRepository.findByToken(token).isPresent();
35+
}
36+
37+
//기존 토큰 지우고 발급(회전)
38+
public String rotateToken(String oldToken) {
39+
Optional<RefreshToken> oldRefreshToken = refreshTokenRepository.findByToken(oldToken);
40+
41+
if (oldRefreshToken.isEmpty()) {
42+
throw new IllegalArgumentException("Invalid refresh token");
43+
}
44+
45+
RefreshToken tokenData = oldRefreshToken.get();
46+
revokeToken(oldToken);
47+
48+
return generateRefreshToken(tokenData.getUserId(), tokenData.getEmail());
49+
}
50+
51+
//삭제
52+
public void revokeToken(String token) {
53+
refreshTokenRepository.deleteByToken(token);
54+
}
55+
56+
//문자열 난수 조합
57+
private String generateSecureToken() {
58+
byte[] randomBytes = new byte[32];
59+
secureRandom.nextBytes(randomBytes);
60+
return Base64.getEncoder().withoutPadding().encodeToString(randomBytes);
61+
}
62+
}

src/main/java/com/back/global/jwt/JwtUtil.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class JwtUtil {
2020
private final SecretKey secretKey;
2121
private final long accessTokenExpiration;
2222
private static final String ACCESS_TOKEN_COOKIE_NAME = "accessToken";
23+
private static final String REFRESH_TOKEN_COOKIE_NAME = "refreshToken";
2324

2425
public JwtUtil(@Value("${custom.jwt.secretKey}") String secretKey,
2526
@Value("${custom.accessToken.expirationSeconds}") long accessTokenExpiration) {

0 commit comments

Comments
 (0)