feat: implement session timeout countdown and UI optimization

This commit is contained in:
leeyj
2026-04-20 16:47:47 +09:00
parent ac58e14c8c
commit b376eedc48
15 changed files with 321 additions and 18 deletions
+21
View File
@@ -0,0 +1,21 @@
# Bug Report: 세션 타임아웃으로 인한 데이터 손실 방지 처리
## 1. 버그 내용
- **현상**: 세션 타임아웃이 발생한 상태에서 사용자가 메모를 저장하려고 하면 API 호출이 실패(401 Unauthorized)하고 로그인 페이지로 리다이렉트됨. 이 과정에서 사용자가 입력한 메모 내용이 보존되지 않고 소실되는 문제 발생.
- **원인**: 세션 타임아웃이 하드코딩(1시간)되어 있어 사용자가 인지하기 어렵고, 프론트엔드에서 세션 만료를 사전에 감지하는 로직이 부재함.
## 2. 조치 사항
- **백엔드 (Flask)**:
- `config.json`을 통해 세션 타임아웃 시간을 분 단위로 설정 가능하도록 변경 (`session_timeout` 필드 추가).
- 보안 및 안정성을 위해 최소 타임아웃 시간을 **10분**으로 제한 (백엔드 강제 적용 로직 포함).
- `/api/auth/status` 엔드포인트를 추가하여 세션 유효 여부를 즉시 확인할 수 있게 함.
- 설정 저장 시 `PERMANENT_SESSION_LIFETIME` 설정을 즉시 업데이트하여 서버 재시작 없이 반영되도록 처리.
- **프론트엔드 (JavaScript/i18n)**:
- 환경설정 모달에 세션 타임아웃 입력 필드 추가.
- 10분 미만 입력 시 경고 알림 및 저장 방지 로직 추가.
- **Heartbeat 기능 구현**: `AppService.startSessionHeartbeat()`를 통해 2분 간격으로 세션 상태를 체크하고, 만료 시 즉시 로그인 페이지로 튕기게(Bounce) 처리하여 저장 시점에 당황하는 상황을 방지함.
- 설정 관련 모든 API 호출을 `API.request`로 통합하여 공통 인증 처리를 수행함.
## 3. 향후 주의사항
- 세션 타임아웃 설정은 브라우저 쿠키의 생명주기와 관련이 있으므로, 설정을 변경한 직후에는 세션이 즉시 갱신되지 않을 수 있음(기존 쿠키 만료까지 대기). 설정 변경 후에는 가급적 로그아웃 후 재로그인을 권장함.
- Heartbeat 주기를 너무 짧게 설정할 경우 서버 트래픽이 증가할 수 있으므로, 현재 최소 타임아웃(10분)의 1/5 수준인 2분으로 유지함.
+18
View File
@@ -0,0 +1,18 @@
# [FEAT] 세션 타임아웃 카운트다운 타이머 구현
## 버그/기능 내용
- 세션이 소리 소문 없이 만료되어 작업 중인 내용이 저장되지 않는 문제를 방지하기 위해, 로그아웃 버튼에 실시간 남은 세션 시간을 표시하는 기능을 추가함.
- 버튼 크기 비대화를 방지하기 위해 "로그아웃" 텍스트를 "종료"(KO) / "EXIT"(EN)로 축약함.
## 조치 사항
1. **로케일 수정**: `static/locales/ko.json`, `en.json`에서 `nav_logout` 값을 축약형으로 변경.
2. **신규 컴포넌트**: `static/js/components/SessionManager.js` 생성.
- 서버 설정(`/api/settings`)의 `session_timeout` 값을 초 단위로 변환하여 관리.
- 1초마다 카운트다운을 수행하고 로그아웃 버튼의 텍스트(`span.text`)를 업데이트.
3. **사용자 활동 감지**: `mousedown`, `keydown`, `touchstart` 이벤트 발생 시 타이머를 원래 설정값으로 리셋.
4. **자동 로그아웃**: 카운트가 `00:00`에 도달하면 알림 표시 후 `/logout`으로 리다이렉트.
5. **통합**: `static/app.js`에서 초기화 코드 추가.
## 향후 주의 사항
- `I18nManager.applyTranslations()`가 실행될 때 `data-i18n` 속성에 의해 타이머 텍스트가 덮어씌워질 수 있으나, `SessionManager`가 1초 단위로 다시 그리므로 시각적 문제는 미미함.
- 브라우저 탭이 비활성 상태(Background)일 때 `setInterval`의 작동 주기가 느려질 수 있으나, 다시 포커스를 얻으면 실제 시간 흐름을 보정하거나 활동 시 리셋되므로 사용성에는 큰 문제가 없음.