
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
package com.takensoft.common.util;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author takensoft
* @since 2025.03.21
* @modification
* since | author | description
* 2025.03.21 | takensoft | 최초 등록
* 2025.05.29 | takensoft | Redis 통합 중복로그인 관리
*
* 세션 로그인 방식의 유틸리티
*/
@Slf4j
@Component
public class SessionUtil {
private final Map<String, HttpSession> sessionMap = new ConcurrentHashMap<>();
private final RedisTemplate<String, String> redisTemplate;
public SessionUtil(RedisTemplate<String, String> redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 세션 등록 - Redis 연동
* 기존 세션 있으면 강제 로그아웃 후 새 세션 등록
*/
public synchronized void registerSession(String mbrId, HttpSession newSession) {
try {
// 1. 기존 메모리 세션 처리
HttpSession oldSession = sessionMap.get(mbrId);
if (oldSession != null && oldSession != newSession) {
try {
oldSession.invalidate();
} catch (IllegalStateException e) {
}
}
// 2. 새 세션을 메모리에 등록
sessionMap.put(mbrId, newSession);
// 3. Redis 동기화는 LoginUtil에서 처리됨
} catch (Exception e) {
}
}
/**
* 세션 ID로 세션 무효화
*/
public void invalidateSessionById(String sessionId) {
try {
boolean found = false;
// 메모리에서 해당 세션 ID를 가진 세션 찾아서 무효화
sessionMap.entrySet().removeIf(entry -> {
HttpSession session = entry.getValue();
if (session != null && session.getId().equals(sessionId)) {
try {
session.invalidate();
return true;
} catch (IllegalStateException e) {
return true;
}
}
return false;
});
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 사용자별 세션 제거 - Redis 연동
*/
public void removeSession(String mbrId) {
try {
// 1. 메모리 세션 무효화
HttpSession session = sessionMap.get(mbrId);
if (session != null) {
try {
session.invalidate();
} catch (IllegalStateException e) {
}
}
sessionMap.remove(mbrId);
// 2. Redis에서도 제거
String sessionKey = "session:" + mbrId;
String deletedSessionId = redisTemplate.opsForValue().get(sessionKey);
if (deletedSessionId != null) {
redisTemplate.delete(sessionKey);
}
} catch (Exception e) {
}
}
/**
* 전체 세션 무효화 - Redis 연동
*/
public void invalidateAllSessions() {
try {
// 1. 모든 메모리 세션 무효화
for (Map.Entry<String, HttpSession> entry : sessionMap.entrySet()) {
HttpSession session = entry.getValue();
if (session != null) {
try {
session.invalidate();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
}
sessionMap.clear();
// 2. Redis에서 모든 세션 키 삭제
try {
var sessionKeys = redisTemplate.keys("session:*");
if (sessionKeys != null && !sessionKeys.isEmpty()) {
redisTemplate.delete(sessionKeys);
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}