0️⃣문제 배경 (JWT의 한계와 Redis 도입의 필요성)
JWT는 서버에 저장하지 않는 토큰 기반 인증 방식이기 때문에 한번 발급되면 유효기한이 끝날 때까지 유효함
즉, 사용자가 로그아웃을 해도 서버는 그 토큰이 유효한지 알 수 없음
이를 해결하기 위해서, Redis에 무효화된 토큰 목록(블랙리스트!)를 저장해두고 인증 요청시마다 체크하면
서버는 특정 토큰을 무효화 된 것으로 간주할 수 있음
1️⃣구현 방식 (로그아웃시)
1. 사용자가 로그아웃 요청을 보냄
2. 서버는 해당 jwt를 Redis의 블랙리스트에 저장
- TTL : 토큰 만료시간까지 설
3. 이후 사용자가 다시 요청하면
- 서버는 Redis에 해당 토큰이 존재하는지 확인
- 존재하면 토큰을 무효 처리 (인증 거부. 로그아웃 처리)
✍🏻예시코드
// 로그아웃 시 Redis에 블랙리스트 등록
public void logout(String token) {
long expiration = jwtUtil.getRemainingTime(token); // JWT 남은 유효시간(ms)
redisTemplate.opsForValue()
.set("blacklist:" + token, "logout", expiration, TimeUnit.MILLISECONDS);
}
// 인증 필터에서 확인
public boolean isBlacklisted(String token) {
return redisTemplate.hasKey("blacklist:" + token);
}
2️⃣보완 전략
- 메모리 이슈 : 토큰이 많아지면 Redis에 부담이 생김
>> Redis의 Eviction 정책 (ex. LRU, LFU)을 설정하여 메모리 초과시 적절히 제거하도록 설정 필요 - 자동 삭제 : TTL을 설정했기 때문에, 토큰 만료 시 자동으로 삭제됨
- 관리 전략
- AccessToken : 로그아웃 시, Redis 블랙리스트에 등록하여 서버가 무효화 판단
- RefreshToken : 별도 저장소(db나 redis)에 관리하여 사용자 id 기반으로 매핑 저장
3️⃣RefreshToken을 redis에 저장하기
로그인 시, 발급한 RefreshToken을 Redis에 저장하고, 사용자 id와 매핑하여 유효성을 직접 확인해야 함
RefreshToken 탈취나 중복 사용을 방지하기 위한 보안 강화 전략임
✍🏻예시코드
// 로그인 시 RefreshToken 저장
redisTemplate.opsForValue().set("refresh:user:1001", refreshToken, 7, TimeUnit.DAYS);
// RefreshToken 유효성 검증
String storedToken = redisTemplate.opsForValue().get("refresh:user:1001");
if (!refreshToken.equals(storedToken)) {
throw new RuntimeException("Invalid refresh token");
}
✅Redis 활용 요약 및 기대효과
- 서버 무효화 : Redis를 활용하여 JWT를 블랙리스트에 등록함으로써 서버 차원의 토큰 무효화가 가능해짐
- 세션 관리 : JWT는 stateless하지만, Redis를 통해 세션 기반 제어가 가능해짐 (강제 로그아웃, 만료 제어 등)
- 확장성 : 로그인 이력 관리, RefreshToken 갱신, 토큰 재사용 방지, 강제 로그아웃 등의 기능으로 보안성을 강화하며 인증 전략도 유연하게 확장 가능해짐
LIST
'👩🏻💻TIL (Today I Learn) > Redis' 카테고리의 다른 글
| 🔔 Redis는 싱글스레드인데 왜 이렇게 빠를까? (3) | 2025.08.07 |
|---|---|
| 블로킹/비블로킹, 동기/비동기 관점에서 본 Redis 메시지 큐 (3) | 2025.08.06 |
| 🔐동시성 제어 정리 : 낙관적 / 비관적 / 분산 락 (2) | 2025.08.05 |