🧭 SSR → CSR 시퀀스 다이어그램
(로그인된 사용자의 페이지 요청 과정)
사용자 브라우저 서버(Node.js, SSR) React 컴포넌트
│ │ │
│ ① 페이지 요청 (예: /mypage) │ │
├──────────────────────────────>│ │
│ │ │
│ │ ② 쿠키나 헤더에서 토큰 확인 │
│ │ (예: Authorization: Bearer ...)│
│ │ │
│ │ ③ React 코드 실행 (SSR 렌더링) │
│ │ └─ setToken(newToken, ...) 호출│
│ │ └─ localStorage 없음 → 상태만 설정
│ │ │
│ │ ④ HTML 완성 (로그인 상태 UI 포함)
│ │ ⑤ HTML 응답 전송
│<─────────────────────────────┤ │
│ │ │
│ ⑥ 브라우저가 HTML 표시 (화면 바로 보임) │
│ │ │
│ ⑦ JS 번들 다운로드 (Hydration 시작) │
│──────────────────────────────>│ │
│ │ │
│ ⑧ 클라이언트 코드 실행 (CSR 단계) │
│ └─ setToken() 다시 호출 │
│ └─ localStorage 사용 가능 → 토큰/만료시각 저장 ✅ │
│ │ │
│ ⑨ 이제 완전한 로그인 상태 유지 (브라우저 localStorage 기반) │
│ │ │
🔍 요약으로 정리하면
| 단계 | 위치 | 하는 일 |
| ① | 브라우저 → 서버 | SSR 페이지 요청 |
| ② | 서버 | 쿠키/헤더에서 토큰 확인 |
| ③ | 서버 | React 렌더링 (HTML 생성) |
| ④~⑤ | 서버 → 브라우저 | HTML 전송 |
| ⑥ | 브라우저 | HTML 즉시 표시 |
| ⑦~⑧ | 브라우저 | JS 실행 (Hydration) |
| ⑨ | 브라우저 | localStorage에 토큰 저장 후 실제 로그인 유지 |
💡 핵심 포인트
- SSR 단계에서는 서버가 토큰을 “참고”만 함 → HTML 렌더링용
- CSR 단계에서는 브라우저가 토큰을 “보관”함 → 실제 로그인 상태 유지
- 이렇게 나누면
- 서버는 빠른 초기 렌더링 (HTML 제공)
- 브라우저는 로그인 유지/상호작용 담당
🧭 SSR → CSR + JWT 만료 관리 전체 흐름
사용자 브라우저 서버(Node.js, SSR) React 컴포넌트
│ │ │
│ ① 페이지 요청 (예: /mypage) │ │
├───────────────────────────────────>│ │
│ │ │
│ │ ② 쿠키/헤더에서 JWT 토큰 확인 │
│ │ └─ 유효한 토큰이면 userInfo 조회 │
│ │ │
│ │ ③ SSR 렌더링 실행 (React 코드) │
│ │ └─ setToken(newToken, expiryMs) 호출
│ │ └─ localStorage 없음 → 상태만 설정
│ │ │
│ │ ④ HTML 완성 (로그인 상태 UI 포함)
│ │ ⑤ HTML 응답 전송
│<───────────────────────────────────┤ │
│ │ │
│ ⑥ 브라우저: HTML 표시 (즉시 화면 표시) │
│ │ │
│ ⑦ JS 번들 다운로드 → Hydration 시작 │
│───────────────────────────────────>│ │
│ │ │
│ ⑧ CSR 진입: setToken() 다시 실행 │
│ └─ localStorage 사용 가능 → 토큰 저장, 만료시각 계산 (현재시간+expiryMs)
│ └─ 전역상태(token, tokenExpiry, isAuthenticated:true) 업데이트 ✅ │
│ │ │
│ ⑨ 사용자 로그인 상태로 앱 이용 │
│ └─ 페이지 전환 시마다 localStorage의 토큰을 사용해 API 요청 │
│ │ │
│ ⑩ 시간이 흐름 (expiryMs 지난 후) │
│ └─ 토큰 만료시각 확인 로직 작동: │
│ if (Date.now() > tokenExpiry) { │
│ localStorage.clear() │
│ set({ token:null, isAuthenticated:false }) ← 자동 로그아웃 🔒│
│ } │
│ │ │
│ ⑪ 이후 요청 시 → 서버는 “만료된 토큰” 감지 │
│ └─ 401 Unauthorized 응답 │
│<───────────────────────────────────┤ │
│ └─ 브라우저: 로그인 페이지로 리다이렉트 │
│ │ │
🧠 단계별 핵심 정리
| 단계 | 위치 | 동작 |
| ①~③ | 서버(SSR) | 토큰 확인 후 HTML 렌더링 |
| ④~⑧ | 클라이언트(CSR) | 토큰 저장(localStorage) + 만료시각 기록 |
| ⑨ | 앱 구동 | 로그인 상태 유지 중 |
| ⑩ | 클라이언트 감시 | 만료시각 도달 시 자동 로그아웃 처리 |
| ⑪ | 서버 | 만료된 토큰으로 접근 시 401 응답 → 재로그인 유도 |
🔒 전체 요약
| 구분 | SSR | CSR |
| 실행 위치 | 서버(Node.js) | 브라우저 |
| localStorage 접근 | ❌ 불가 | ✅ 가능 |
| 토큰 역할 | 단순 렌더링용(참조) | 실제 로그인 상태 유지 |
| 만료 처리 | 없음 (렌더링만) | JS에서 시간 감시 후 자동 로그아웃 |
| 서버 반응 | 만료된 토큰 → 401 응답 | 로그인 페이지로 리다이렉 |
'Sprint_FESI11 > Project' 카테고리의 다른 글
| 웹이 SSR(서버가 코드를 해석해서 HTML을 만들어주는 구조) 를 유지하는 존재 이유 (0) | 2025.10.16 |
|---|---|
| JSP vs ASP vs SSR (0) | 2025.10.16 |
| 서버는 렌더링만 하는데, 왜 토큰을 가지고 있지? (0) | 2025.10.16 |
| SSR 환경에서 단순히 상태만 바꿔준다는 것의 의미 (0) | 2025.10.16 |
| 로그인 토큰을 저장하고 관리하는 함수 (0) | 2025.10.16 |