Java 애플리케이션에서 JWT 토큰을 사용할 때 중복 로그인을 방지하기 위해 세션 추적 메커니즘을 사용할 수 있습니다. 다음은 이 접근 방식을 보여주는 예제 코드입니다.
1. 세션 관리를 처리할 SessionManager 클래스를 만듭니다.
import java.util.HashMap;
import java.util.Map;
public class SessionManager {
private static SessionManager instance;
private Map<String, String> activeSessions;
private SessionManager() {
activeSessions = new HashMap<>();
}
public static synchronized SessionManager getInstance() {
if (instance == null) {
instance = new SessionManager();
}
return instance;
}
public synchronized void addSession(String userId, String sessionId) {
activeSessions.put(userId, sessionId);
}
public synchronized void removeSession(String userId) {
activeSessions.remove(userId);
}
public synchronized boolean isSessionActive(String userId, String sessionId) {
String activeSessionId = activeSessions.get(userId);
return activeSessionId != null && activeSessionId.equals(sessionId);
}
}
2. 로그인 엔드포인트에서 인증에 성공한 후 JWT 토큰을 생성하고 세션 정보를 저장합니다.
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
public class LoginController {
private static final String SECRET_KEY = "yourSecretKey";
private SessionManager sessionManager;
public LoginController() {
sessionManager = SessionManager.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 the session manager
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";
}
}
3. 엔드포인트에서 JWT 토큰의 유효성을 검사하고 세션이 활성 상태인지 확인합니다.
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
public class ProtectedController {
private static final String SECRET_KEY = "yourSecretKey";
private SessionManager sessionManager;
public ProtectedController() {
sessionManager = SessionManager.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
return sessionManager.isSessionActive(userId, sessionId);
} catch (Exception e) {
// Invalid token or session expired
return false;
}
}
}
이 예제에서 SessionManager 클래스는 HashMap을 사용하여 활성 세션을 추적합니다. LoginController는 세션 ID를 생성하여 세션 관리자에 저장하고 세션 ID를 클레임으로 사용하여 JWT 토큰을 생성합니다. ProtectedController는 JWT 토큰의 유효성을 검사하고 세션 ID를 추출하며 사용자의 활성 세션과 일치하는지 확인합니다.
JWT 토큰 서명을 위해 "yourSecretKey"를 시크릿 키로 교체해야 합니다. 또한 generateSessionId() 메서드에서 고유한 세션 ID를 생성하는 고유한 논리를 구현합니다.