학습데이터 관리 목록 순서 변경, 주석추가
This commit is contained in:
@@ -19,6 +19,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
||||
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
|
||||
// JWT 필터를 타지 않게 할 URL 패턴들
|
||||
private static final String[] EXCLUDE_PATHS = {
|
||||
"/api/auth/signin", "/api/auth/refresh", "/api/auth/logout", "/api/members/*/password"
|
||||
};
|
||||
@@ -30,8 +31,10 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
|
||||
// HTTP 요청 헤더에서 JWT 토큰 꺼내기
|
||||
String token = resolveToken(request);
|
||||
|
||||
// JWT 토큰을 검증하고, 인증된 사용자로 SecurityContext에 등록
|
||||
if (token != null && jwtTokenProvider.isValidToken(token)) {
|
||||
String username = jwtTokenProvider.getSubject(token);
|
||||
|
||||
@@ -57,7 +60,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
return false;
|
||||
}
|
||||
|
||||
// /api/members/{memberId}/password
|
||||
// HTTP 요청 헤더에서 JWT 토큰 꺼내기
|
||||
private String resolveToken(HttpServletRequest request) {
|
||||
String bearer = request.getHeader("Authorization");
|
||||
if (bearer != null && bearer.startsWith("Bearer ")) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import javax.crypto.SecretKey;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/** 토큰 생성 */
|
||||
@Component
|
||||
public class JwtTokenProvider {
|
||||
|
||||
@@ -31,10 +32,12 @@ public class JwtTokenProvider {
|
||||
this.key = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
// Access Token 생성
|
||||
public String createAccessToken(String subject) {
|
||||
return createToken(subject, accessTokenValidityInMs);
|
||||
}
|
||||
|
||||
// Refresh Token 생성
|
||||
public String createRefreshToken(String subject) {
|
||||
return createToken(subject, refreshTokenValidityInMs);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.core.ValueOperations;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/** redis token handler */
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class RefreshTokenService {
|
||||
@@ -13,16 +14,33 @@ public class RefreshTokenService {
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private static final String PREFIX = "RT:";
|
||||
|
||||
/**
|
||||
* Refresh Token 저장
|
||||
*
|
||||
* @param username 사용자 식별값 (보통 username or userId)
|
||||
* @param refreshToken 발급된 Refresh Token
|
||||
* @param ttlMillis 토큰 만료 시간 (밀리초 단위)
|
||||
*/
|
||||
public void save(String username, String refreshToken, long ttlMillis) {
|
||||
ValueOperations<String, String> ops = redisTemplate.opsForValue();
|
||||
ops.set(PREFIX + username, refreshToken, Duration.ofMillis(ttlMillis));
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh Token 검증
|
||||
*
|
||||
* <p>1. Redis에 저장된 값 조회 2. 클라이언트가 보낸 refreshToken과 비교 3. 동일하면 true
|
||||
*/
|
||||
public boolean validate(String username, String refreshToken) {
|
||||
String stored = redisTemplate.opsForValue().get(PREFIX + username);
|
||||
return stored != null && stored.equals(refreshToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh Token 삭제
|
||||
*
|
||||
* <p>로그아웃 시 호출 Redis에서 해당 사용자 토큰 제거
|
||||
*/
|
||||
public void delete(String username) {
|
||||
redisTemplate.delete(PREFIX + username);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user