6.8 KiB
6.8 KiB
세션 연장 Confirm 적용 가이드
1) 목적과 원칙
JWT 만료 5분 전에 "로그인을 연장하시겠습니까?" confirm을 띄우고, 선택에 따라 세션을 연장하는 UX를 서비스 앱에 적용하기 위한 가이드입니다.
이 문서는 서비스별 인증 처리 리팩토링 가이드의 후속 단계입니다.
핵심 원칙:
- confirm UX는
@common/componentsHeader의useSessionExtendConfirm이 담당한다. - confirm 확인 →
authService.silentRefresh() - confirm 취소 →
authService.declineSessionExtend() - 앱은
ConfirmProvider계층과authService주입을 맞춘다.
적용 완료: cs, as, st
2) 선행 조건
리팩토링 가이드 체크리스트를 통과한 서비스만 진행한다.
| 항목 | 리팩토링 가이드 |
|---|---|
authService (silentRefresh, declineSessionExtend) |
4-4 |
BaseLayout에 authService 주입 |
4-7 |
3) 목표 아키텍처
3-1. 레이어 책임
| 레이어 | 위치 | 역할 |
|---|---|---|
| JWT 시간 계산 | @common/auth jwt-utils.ts |
getRemainingMs, confirm 버퍼 상수 |
| 토큰·정리 | @common/auth token-manager.ts |
setToken, clearRefreshTimer, clearAuthToken |
| API 오케스트레이션 | entities/auth/api/auth-service.ts |
silentRefresh, declineSessionExtend |
| confirm UX | @common/components Header |
카운트다운 + 5분 전 confirm |
| 앱 진입점 | entities/auth/lib/auth-wrapper.tsx |
auth 체크, auth:logout |
| 레이아웃 | layout / BaseLayout wrapper | authService → Header |
| UI 쉘 | app/providers/app-provider.tsx |
ConfirmProvider, ConfirmDialog |
3-2. 런타임 흐름
sequenceDiagram
participant Login as authService.login
participant Header as Header
participant User as 사용자
participant API as authService.silentRefresh
Login->>Login: setToken
Header->>Header: confirm 예약(exp - 5분)
Note over Header: 만료 5분 전
Header->>User: 로그인을 연장하시겠습니까?
alt 확인
User->>API: silentRefresh()
API->>API: setToken
Header->>Header: confirm 타이머 재설정
else 취소
Header->>Header: declineSessionExtend()
end
| 시점 | 동작 | 담당 |
|---|---|---|
| 로그인 / silentRefresh 성공 | 토큰 저장 | authService |
| 만료 5분 전 | confirm 표시 | Header → useSessionExtendConfirm |
| confirm 확인 | silentRefresh + confirm 타이머 재설정 |
Header → authService.silentRefresh |
| confirm 취소 | declineSessionExtend |
Header → authService.declineSessionExtend |
| 토큰 완전 만료 | logout | Header |
4) 공통 계약
4-1. 시간 버퍼 (getRemainingMs)
파일: packages/common/auth/jwt-utils.ts
export const SESSION_EXTEND_CONFIRM_BUFFER_MS = 5 * 60_000; // confirm: 만료 5분 전
getRemainingMs(token, SESSION_EXTEND_CONFIRM_BUFFER_MS); // → confirm 타이머 delay
getRemainingMs(token, 0) > 0; // → 토큰 미만료 여부
4-2. Header ↔ AuthService
공통 Header가 아래처럼 연결한다.
useSessionExtendConfirm({
enabled:
mounted &&
isLoggedIn &&
!viewOnly &&
!!authService &&
!isAtLoginRedirectUrl(getAuthLoginRedirectUrl()),
getAccessToken: () => getCookie(appConfig.CLAIM_NAME ?? ""),
silentRefresh: authService?.silentRefresh ?? (async () => {}),
declineSessionExtend: authService?.declineSessionExtend ?? (() => {}),
});
4-3. Provider 계층
ConfirmProvider
└─ AuthWrapper
└─ … → BaseLayout → Header
└─ ConfirmDialog
5) 적용 순서
5-1. AppProvider — ConfirmProvider 마운트
파일: app/providers/app-provider.tsx
<ConfirmProvider>
<AuthWrapper>
{children}
<ConfirmDialog />
</AuthWrapper>
</ConfirmProvider>
참고: apps/cs/src/app/providers/app-provider.tsx
5-2. BaseLayout — authService 전달
import { authService } from "@/entities/auth";
<BaseLayout authService={authService} /* ... */>
{children}
</BaseLayout>
5-3. authService — declineSessionExtend
리팩토링 4-4에서 이미 구현했다면 확인만 한다.
export const authService: AuthService = {
login,
silentRefresh,
declineSessionExtend: clearRefreshTimer,
logout,
};
6) 엣지 케이스
| 상황 | 동작 |
|---|---|
| 토큰 유효 시간 < 5분 | 진입 즉시 confirm |
| confirm 취소 | declineSessionExtend() + 동일 JWT에 재표시 안 함 |
| confirm 확인 | silentRefresh() → 새 토큰 기준 confirm 타이머 재설정 |
silentRefresh 실패 |
auth:logout → AuthWrapper 리다이렉트 |
| 로그아웃 | clearAuthToken, 훅 cleanup |
| 페이지 새로고침 | Header가 confirm 타이머 재예약 |
7) 적용 체크리스트
ConfirmProvider>AuthWrapper>BaseLayout>Header계층ConfirmDialog가ConfirmProvider하위에 마운트됨BaseLayout에authService전달authService.declineSessionExtend구현- 만료 5분 전 confirm 노출
- 확인 클릭 시
SILENT_REFRESH호출 - 취소 후 세션이 연장되지 않음
8) 검증 방법
- 로그인 후 JWT
exp가 5분 이내가 되도록 대기하거나 테스트 토큰 사용 - confirm 문구
"로그인을 연장하시겠습니까?"표시 확인 - 확인 → Network에서
SILENT_REFRESHPUT, 쿠키 갱신, confirm 재예약 - 취소 → 만료 시 로그아웃/리다이렉트
- 새로고침 후 confirm 타이머 복구
9) 참고 구현
| 앱 | auth-service | BaseLayout / layout | AppProvider |
|---|---|---|---|
| as (기준) | apps/as/src/entities/auth/api/auth-service.ts |
apps/as/src/app/layouts/base-layout.tsx |
(동등 Provider) |
| cs | apps/cs/src/entities/auth/api/auth-service.ts |
apps/cs/app/(main)/(with-base-layout)/layout.tsx |
apps/cs/src/app/providers/app-provider.tsx |
| st | apps/st/src/entities/auth/api/auth-service.ts |
apps/st/app/(main)/(with-base-layout)/layout.tsx |
(동등 Provider) |
공통:
packages/common/components/src/ui/header/index.tsxpackages/common/components/src/lib/use-session-extend-confirm.ts
10) 관련 문서
- 서비스별 인증 처리 리팩토링 가이드
packages/common/auth/README.md