# 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`) |