- _index.md: 문서 목록 및 버전 관리 - 01~09: 아키텍처, API패턴, 컴포넌트, 폼, 스타일, 인증, 대시보드, 컨벤션 - 10: 문서 API 연동 스펙 (api-specs에서 이관) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.9 KiB
4.9 KiB
07. 인증 흐름
대상: 프론트엔드/백엔드 개발자 버전: 1.0.0 최종 수정: 2026-03-09
1. 인증 아키텍처 요약
┌─────────────────────────────────────────────────────┐
│ 브라우저 │
│ │
│ [React 컴포넌트] │
│ │ fetch('/api/proxy/...') │
│ │ (토큰 전송 안함 — 쿠키가 자동 포함) │
│ ▼ │
│ [Next.js API Proxy] │
│ │ 쿠키에서 access_token 읽기 │
│ │ Authorization: Bearer {token} 헤더 추가 │
│ ▼ │
│ [authenticatedFetch 게이트웨이] │
│ │ 401 → refresh → retry (자동) │
│ ▼ │
│ [PHP Laravel Backend] │
│ │
│ 쿠키: │
│ ├── access_token (HttpOnly, 2시간) │
│ ├── refresh_token (HttpOnly, 7일) │
│ └── is_authenticated (non-HttpOnly, 상태 확인용) │
└─────────────────────────────────────────────────────┘
2. 왜 HttpOnly 쿠키?
| 방식 | XSS 취약 | 토큰 갱신 | SAM 채택 |
|---|---|---|---|
| localStorage | 취약 (JS 접근 가능) | 직접 구현 | ❌ |
| 일반 쿠키 | 취약 (JS 접근 가능) | 직접 구현 | ❌ |
| HttpOnly 쿠키 | 안전 (JS 접근 불가) | 프록시에서 처리 | ✅ |
- JavaScript로 토큰을 읽을 수 없음 → XSS 공격에 안전
- 대신 서버(Next.js 프록시)에서만 읽기 가능 → 프록시 패턴 필수
3. 로그인 흐름
1. 사용자 → 로그인 폼 입력 (email, password)
2. 프론트 → POST /api/proxy/auth/login { email, password }
3. 프록시 → POST /api/v1/auth/login (Laravel)
4. Laravel → { access_token, refresh_token, expires_in }
5. 프록시 → Set-Cookie 3개 설정:
- access_token=xxx; HttpOnly; Max-Age=7200
- refresh_token=xxx; HttpOnly; Max-Age=604800
- is_authenticated=true; Max-Age=7200
6. 프론트 → 대시보드로 이동
4. API 호출 시 토큰 흐름
1. 컴포넌트 → Server Action 호출 (또는 fetch /api/proxy/...)
2. Server Action → serverFetch → authenticatedFetch
- 쿠키에서 access_token 읽기
- Authorization: Bearer {token} 헤더 추가
3. 백엔드 응답:
- 200 OK → 정상 처리
- 401 → 토큰 만료 (아래 갱신 흐름)
5. 토큰 갱신 (자동)
1. API 호출 → 401 Unauthorized 응답
2. authenticatedFetch 감지:
a. refresh_token으로 POST /api/v1/auth/refresh
b. 새 access_token 발급
c. 새 토큰으로 원래 요청 재시도 (1회)
3. 결과:
- 재시도 성공 → 정상 응답 + 새 쿠키 설정
- 재시도 실패 → 쿠키 삭제 + 로그인 페이지 이동
중요: 동시에 여러 요청이 401을 받으면, refresh는 1번만 실행 (globalThis 캐싱으로 중복 방지)
6. 미들웨어 (middleware.ts)
요청 단계에서의 인증 검사 (토큰 갱신과는 별개):
요청 들어옴
↓
1. 내부 요청 필터링 (_next/*)
2. IE 브라우저 차단
3. 다국어 처리 (ko, en)
4. /dev/ 경로 프로덕션 차단
5. 봇 탐지 (40+ 패턴 차단)
6. API/정적 파일 통과
7. 인증 확인:
- 비인증 사용자 → 로그인 페이지 리다이렉트
- 인증된 사용자가 로그인 페이지 접근 → 대시보드 리다이렉트
8. 보안 헤더 설정 (X-Robots-Tag, CSP 등)
7. 프론트엔드 개발자 체크리스트
| 항목 | 설명 |
|---|---|
| 직접 토큰 관리 금지 | localStorage/sessionStorage에 토큰 저장 ❌ |
| fetch 직접 호출 금지 | Server Action 또는 /api/proxy/ 경로만 사용 |
| 인증 상태 확인 | is_authenticated 쿠키 (non-HttpOnly) 또는 useAuthGuard() |
| 401 처리 | authenticatedFetch가 자동 처리 — 수동 처리 불필요 |
8. 백엔드 개발자 참고
| 항목 | 내용 |
|---|---|
| 인증 방식 | Bearer Token (Authorization 헤더) |
| 토큰 발급 | POST /api/v1/auth/login |
| 토큰 갱신 | POST /api/v1/auth/refresh |
| 401 응답 시 | 프론트가 자동 refresh → retry |
| API Key | X-API-KEY 헤더 (환경변수: API_KEY) |