Java 애플리케이션에서 JWT 토큰을 사용할 때 Redis를 사용한 중복 로그인을 방지하기 위해 Redis를 분산 캐시로 활용하여 세션 정보를 저장할 수 있습니다. 다음은 이 접근 방식을 보여주는 예제 코드입니다.
1. 프로젝트 종속성에 Redis Java 클라이언트 라이브러리를 추가했는지 확인해야 합니다. 예를 들어 Jedis를 사용할 수 있습니다.
2. Redis를 사용하여 세션 관리를 처리할 RedisSessionManager 클래스를 만듭니다.
import redis.clients.jedis.Jedis;
public class RedisSessionManager {
private static RedisSessionManager instance;
private Jedis jedis;
private RedisSessionManager() {
// Initialize the Redis connection
jedis = new Jedis("localhost"); // Replace with your Redis server details
}
public static synchronized RedisSessionManager getInstance() {
if (instance == null) {
instance = new RedisSessionManager();
}
return instance;
}
public void addSession(String userId, String sessionId) {
jedis.set(userId, sessionId);
}
public void removeSession(String userId) {
jedis.del(userId);
}
public boolean isSessionActive(String userId, String sessionId) {
String activeSessionId = jedis.get(userId);
return activeSessionId != null && activeSessionId.equals(sessionId);
}
}
3. 로그인 엔드포인트에서 인증에 성공한 후 JWT 토큰을 생성하고 세션 정보를 Redis에 저장합니다.
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
public class LoginController {
private static final String SECRET_KEY = "yourSecretKey";
private RedisSessionManager sessionManager;
public LoginController() {
sessionManager = RedisSessionManager.getInstance();
}
public String login(String userId) {
// Authenticate the user and retrieve their unique user ID
// Generate a session ID
String sessionId = generateSessionId();
// Store the session in Redis
sessionManager.addSession(userId, sessionId);
// Create the JWT token with the session ID as a claim
String token = Jwts.builder()
.claim("sessionId", sessionId)
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
return token;
}
private String generateSessionId() {
// Implement your own logic to generate a unique session ID
// For example, you can use UUID.randomUUID().toString()
return "uniqueSessionId";
}
}
4. 엔드포인트에서 JWT 토큰의 유효성을 검사하고 Redis에서 세션이 활성 상태인지 확인합니다.
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
public class ProtectedController {
private static final String SECRET_KEY = "yourSecretKey";
private RedisSessionManager sessionManager;
public ProtectedController() {
sessionManager = RedisSessionManager.getInstance();
}
public boolean isRequestAuthorized(String token) {
try {
// Parse the JWT token and extract the session ID
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
String userId = claims.getSubject();
String sessionId = (String) claims.get("sessionId");
// Check if the session is active in Redis
return sessionManager.isSessionActive(userId, sessionId);
} catch (Exception e) {
// Invalid token or session expired
return false;
}
}
}
이 예에서 RedisSessionManager 클래스는 Redis 연결을 사용하여 세션 정보를 저장합니다. LoginController는 세션 ID를 생성하고 사용자 ID를 키로 사용하여 Redis에 저장하고 세션 ID를 클레임으로 사용하여 JWT 토큰을 생성합니다.