HttpSessionListener를 이용해 중복로그인을 방지할 수 있는데, 이번 프로젝트에는 HttpSessionListener를 통해 session 만료 시간이 되면 WebSocket을 통해 message를 전달하여 자동 로그아웃시키는 기능을 구현하였다.
HttpSessionListener의 객체는 Session이 생성되거나 제거될 때 발생하는 이벤트를 제공해주어 등록만해주면 세션을 통제할 수 있다.
@WebListener
//@RequiredArgsConstructor
public class SessionConfig implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent hse) {
//세션 생성시
}
@Override
public void sessionDestroyed(HttpSessionEvent hse) {
//세션 삭제시
}
}
HttpSessionListener는 EventListener를 상속받아 구현되어 있고 sessionCreated와 sessionDestroyed를 상속받는다.
메소드명 그대로 sessionCreated는 세션이 생성될 때 동작하며, sessionDestroyed는 세션이 삭제될 때 생성된다.
- sessionCreated : 이 메서드가 호출되는 시점은 session 이 생성되는 시점으로, 동일 sessionId 에서는 1회만 호출된다.
- sessionDestroved : 마찬가지로 세션이 invaild 되는 시점에 호출되며, setMaxInactiveInterval 에 지정해 놓은 세션 타임아웃이다. 하여도 동일하게 호출된다.
int timeout = 3600;
private final AtomicInteger counter = new AtomicInteger();
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
httpSessionEvent.getSession().setMaxInactiveInterval(timeout); //sec
counter.incrementAndGet();
updateSessionCounter(httpSessionEvent);
}
private void updateSessionCounter(HttpSessionEvent httpSessionEvent) {
httpSessionEvent.getSession().getServletContext().setAttribute("activeSession", counter.get());
}
private final String sessionTopic = "/topic/session";
private final SimpMessagingTemplate simpMessagingTemplate;
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
SessionUser sessionUser = (SessionUser) httpSessionEvent.getSession().getAttribute(SessionUser.SESSION_KEY);
counter.decrementAndGet();
updateSessionCounter(httpSessionEvent);
if ((System.currentTimeMillis() - httpSessionEvent.getSession().getLastAccessedTime()) / 1000 >= timeout) {
simpMessagingTemplate.convertAndSend(sessionTopic, new WebSocketMessage("server", "success", "세션이 만료되었습니다.", null));
}
}
나아가 AtomicInteger를 사용하여 모든 활성 세션을 추적하는데,
SessionListener 안에서 사용한 AtomicInteger는 원자성을 보장하는 integer이다.
AtomicInteger클래스가 값을 읽고 쓰는 동안 변경되지 않는다는 걸 보장하여 동기화 문제를 해결해준다.
참고
https://www.javadevjournal.com/spring-boot/spring-boot-session-listener/
https://cornswrold.tistory.com/278
https://myhappyman.tistory.com/116
https://hhseong.tistory.com/179
'Web > Else' 카테고리의 다른 글
Intellij 사용 팁(추가) (0) | 2021.11.25 |
---|---|
[Maven]빌드하여 jar 파일 만들기 (0) | 2021.11.16 |
[Web]Token 기반 인증 (0) | 2021.11.11 |
[Web]Maven LifeCycle (0) | 2021.11.04 |
[Web]multipart/form-data (0) | 2021.10.28 |