← 목록으로
트러블슈팅

세션 타임아웃

좀비 세션 타임아웃을 통한 문제해결

👁 0

문제 상황

현재 화면과 서버 양쪽에서 세션 타이머를 관리하고 있다.

  • 서버 세션 만료 시간 : 1800s
  • 화면 세션 로직 : 만료 5분 전 안내 팝업, 미응답 시 30분 후 세션 삭제

첫째, 절전모드 진입 후 복귀 시 세션이 유지되는 현상이었다.

테스트 결과, 절전 상태에서도 브라우저의 JavaScript 타이머가 멈추거나 지연되어 세션이 정상적으로 만료되지 않았다. 그 결과, 사용자는 세션이 만료된 줄 알고 있었지만 실제로는 서버 세션이 계속 유지되고 있었다.

둘째, 동일 브라우저 내 여러 탭 간 세션 타이머가 독립적으로 동작했다.

사용자가 한 탭에서 작업을 이어가면 다른 탭의 타이머는 그대로 만료되는 현상이다.(만료될 경우 로그아웃 시그널을 보낸다.)




활동 중인 탭까지 강제 로그아웃되는 문제가 발생했다.

그리고 또 다른 문제가 발생하였다. 동일 브라우저이나 브라우저 별 타이머가 별도로 돌고 있다는 것이다. 그렇다는 것은 두개의 업무창에서 한곳에서만 활동을 하게 될경우 자동으로 반대 화면에선 리프레쉬 되지 않는 현상이 발생하였다 결국 그렇게 사용하지 않는 페이지에서 세션 타임아웃이 된다면 활동중인 페이지 내에서 자동으로 로그아웃이 되는 현상까지 발견하였다.

사용자 입장으로 과제를 등록하고있을 때 튕기는 현상이면 치명적이라 생각한다.


원인 분석

절전모드의 경우 CPU, 디스크, 메모리 접근을 최소한으로 줄여 전력 소모를 줄이는 모드로 JS는 돌아가긴한다. 아마 브라우저별로 다르겠지만 확실한건 JS를 믿어서는 안된다는것이다.


참고자료 https://developer.chrome.com/blog/timer-throttling-in-chrome-88?utm_source=chatgpt.com&hl=ko


해결

해당 문제를 찾아보니, 주기적으로 서버로 url를 보내 메세지를 불러오는 작업을한다 그로인해 세션이 끊이지 않는 아주 간단한 문제였다! 하지만 화면에서 처리가 되어있기에 특별히 문제가 없어 보였던것 뿐이였다.


// 잘못된 예시
fetch("/api/test", {
  method: "POST",
  credentials: "include"  // 세션 갱신 유발
});

fetch("/api/test", {
  method: "POST",
  credentials: "omit"     // 쿠키 미포함 → 세션 무갱신
});

요청에 쿠키를 포함하여 처리하게 될 경우 세션이 초기화되는 이슈가 있어 이 부분을 간단하게 수정하게 될 경우 세션초기화를 막을수 있게 되었다.

사용자 입장에서의 또 다른 문제

  1. 절전모드를 사용하게 될 경우 또 사용자가 세션 로그아웃이 된것처럼 보이지 않는 혼선이 있을 수 있다. 같은 브라우저라도 js 가 따로 돌기 때문에 또 업무창이 동기화 되지않았다. 이로 인한 문제점으로 브라우저는 이미 세션이 끊긴상태로 작업하고 저장을 하게 된다면 로그인 창으로 가게 될것이다.
  2. 같은 브라우저라도 세션 타이머가 따로 돌아간다… 이 부분의 경우 A 화면30분, B화면 8분으로 세션타이머가 돌아가고 있다 가정해보자. A에서 작업하고 있어도 B화면에서 8분이 되면 세션 만료 처리를 해버려 A화면 또한 세션이 끊기게 되어있다.


또 다른 문제에 대한 해법

1번과 2번을 해결하기 위해 localStorage를 사용하게 하였다 왜냐하면 브라우저 간에 localStorage는 공유 되기 때문이다. 브라우저간에 세션시간을 localStorage를 통해 공유함으로서 같은 브라우저 화면들간의 결합이 생겼다. 또, 다음 작업으로 A화면에서 로그아웃을 할경우 B 화면에서 로그아웃 처리를 해야 사용자에게 혼선을 안 줄수 있다. 이 문제를 해결하기 위해 브로드케스팅 작업을 진행하였다. 로그아웃을 보낼 때 브로드 캐스팅을 통해 화면들에게 무분별한 요청을 보내어 화면을 제어할수 있게 되었다. 마지막으로 절전모드의 경우 연산을 통한 데이터 처리를 통해 해결하였다. localStorage에서 시간을 저장하여 그 시간을 현재시간과 연산하여 30분이 되었을 경우 세션이 만료되게 끔 조정하였다.

💡
예외사항
  1. 세션작업을 진행했을 경우에도 무조건 서버에서 한 번 더 처리를 진행하였다.
  2. localStorage값을 0과 30 사이의 값만 연산되도록 처리하였다.


마치며..

해당 문제를 해결하며 특수케이스를 확인하고 예외사항에 대해 보다 명확하게 체크하게 되었고 공식문서를 많이 보는 법을 배웠으며 사용자 편의성을 중점으로 코드 짜도록 처리 방식을 생각하였다.


💬 댓글 0

불러오는 중...