# 인증 시스템 구현 가이드

## 📋 개요

Laravel PHP 백엔드와 Next.js 15 프론트엔드 간의 3가지 인증 방식을 지원하는 통합 인증 시스템

---

## 🔐 지원 인증 방식

### 1️⃣ Sanctum Session (웹 사용자)
- **대상**: 웹 브라우저 사용자
- **방식**: HTTP-only 쿠키 기반 세션
- **보안**: XSS 방어 + CSRF 토큰
- **Stateful**: Yes

### 2️⃣ Bearer Token (모바일/SPA)
- **대상**: 모바일 앱, 외부 SPA
- **방식**: Authorization: Bearer {token}
- **보안**: 토큰 만료 시간 관리
- **Stateful**: No

### 3️⃣ API Key (시스템 간 통신)
- **대상**: 서버 간 통신, 백그라운드 작업
- **방식**: X-API-KEY: {key}
- **보안**: 서버 사이드 전용 (환경 변수)
- **Stateful**: No

---

## 📁 파일 구조

```
src/
├─ lib/api/
│  ├─ client.ts                    # 통합 HTTP Client (3가지 인증 방식)
│  │
│  └─ auth/
│     ├─ types.ts                  # 인증 타입 정의
│     ├─ auth-config.ts            # 인증 설정 (라우트, URL)
│     │
│     ├─ sanctum-client.ts         # Sanctum 전용 클라이언트
│     ├─ bearer-client.ts          # Bearer 토큰 클라이언트
│     ├─ api-key-client.ts         # API Key 클라이언트
│     │
│     ├─ token-storage.ts          # Bearer 토큰 저장 관리
│     ├─ api-key-validator.ts      # API Key 검증 유틸
│     └─ server-auth.ts            # 서버 컴포넌트 인증 유틸
│
├─ contexts/
│  └─ AuthContext.tsx              # 클라이언트 인증 상태 관리
│
├─ middleware.ts                   # 통합 미들웨어 (Bot + Auth + i18n)
│
└─ app/[locale]/
   ├─ (auth)/
   │  └─ login/page.tsx            # 로그인 페이지
   │
   └─ (protected)/
      └─ dashboard/page.tsx        # 보호된 페이지
```

---

## 🔧 환경 변수 설정

### .env.local (실제 키 값)
```env
# API Configuration
NEXT_PUBLIC_API_URL=https://api.5130.co.kr
NEXT_PUBLIC_FRONTEND_URL=http://localhost:3000

# Authentication Mode
NEXT_PUBLIC_AUTH_MODE=sanctum

# API Key (서버 사이드 전용 - 절대 공개 금지!)
API_KEY=42Jfwc6EaRQ04GNRmLR5kzJp5UudSOzGGqjmdk1a
```

### .env.example (템플릿)
```env
NEXT_PUBLIC_API_URL=https://api.5130.co.kr
NEXT_PUBLIC_FRONTEND_URL=http://localhost:3000
NEXT_PUBLIC_AUTH_MODE=sanctum
API_KEY=your-secret-api-key-here
```

---

## 🎯 구현 단계

### Phase 1: 핵심 인프라 (필수)
1. `lib/api/auth/types.ts` - 타입 정의
2. `lib/api/auth/auth-config.ts` - 인증 설정
3. `lib/api/client.ts` - 통합 HTTP 클라이언트
4. `lib/api/auth/sanctum-client.ts` - Sanctum 클라이언트

### Phase 2: Middleware 통합
1. `middleware.ts` 확장 - 인증 체크 로직 추가
2. 라우트 보호 구현 (protected/guest-only)

### Phase 3: 로그인 페이지
1. `app/[locale]/(auth)/login/page.tsx`
2. 기존 validation schema 활용

### Phase 4: 보호된 페이지
1. `app/[locale]/(protected)/dashboard/page.tsx`
2. Server Component로 구현

---

## 🔒 보안 고려사항

### 환경 변수 보안
```yaml
✅ NEXT_PUBLIC_*: 브라우저 노출 가능
❌ API_KEY: 절대 NEXT_PUBLIC_ 붙이지 말 것!
✅ .env.local은 .gitignore에 포함됨
```

### 인증 방식별 보안
```yaml
Sanctum:
  ✅ HTTP-only 쿠키 (XSS 방어)
  ✅ CSRF 토큰 자동 처리
  ✅ Same-Site: Lax

Bearer Token:
  ⚠️ localStorage 사용 (XSS 취약)
  ✅ 토큰 만료 시간 체크
  ✅ Refresh token 권장

API Key:
  ⚠️ 서버 사이드 전용
  ✅ 환경 변수 관리
  ✅ 주기적 갱신 대비
```

---

## 📊 Middleware 인증 플로우

```
Request
  ↓
1. Bot Detection (기존)
  ├─ Bot → 403 Forbidden
  └─ Human → Continue
  ↓
2. Static Files Check
  ├─ Static → Skip Auth
  └─ Dynamic → Continue
  ↓
3. Public Routes Check
  ├─ Public → Skip Auth
  └─ Protected → Continue
  ↓
4. Authentication Check
  ├─ Sanctum Session Cookie
  ├─ Bearer Token (Authorization header)
  └─ API Key (X-API-KEY header)
  ↓
5. Protected Routes Guard
  ├─ Authenticated → Allow
  └─ Not Authenticated → Redirect /login
  ↓
6. Guest Only Routes
  ├─ Authenticated → Redirect /dashboard
  └─ Not Authenticated → Allow
  ↓
7. i18n Routing
  ↓
Response
```

---

## 🚀 API 엔드포인트

### 로그인
```
POST /api/v1/login
Content-Type: application/json

Request:
{
  "user_id": "hamss",
  "user_pwd": "StrongPass!1234"
}

Response (성공):
{
  "user": {
    "id": 1,
    "name": "홍길동",
    "email": "hamss@example.com"
  },
  "message": "로그인 성공"
}

Cookie: laravel_session=xxx; HttpOnly; SameSite=Lax
```

### 로그아웃
```
POST /api/v1/logout

Response:
{
  "message": "로그아웃 성공"
}
```

### 현재 사용자 정보
```
GET /api/user
Cookie: laravel_session=xxx

Response:
{
  "id": 1,
  "name": "홍길동",
  "email": "hamss@example.com"
}
```

---

## 📝 사용 예시

### 1. Sanctum 로그인 (웹 사용자)
```typescript
import { sanctumClient } from '@/lib/api/auth/sanctum-client';

const user = await sanctumClient.login({
  user_id: 'hamss',
  user_pwd: 'StrongPass!1234'
});
```

### 2. API Key 요청 (서버 사이드)
```typescript
import { createApiKeyClient } from '@/lib/api/auth/api-key-client';

const client = createApiKeyClient();
const data = await client.fetchData('/api/external-data');
```

### 3. Bearer Token 로그인 (모바일)
```typescript
import { bearerClient } from '@/lib/api/auth/bearer-client';

const user = await bearerClient.login({
  email: 'user@example.com',
  password: 'password'
});
```

---

## ⚠️ 주의사항

### API Key 갱신
- PHP 팀에서 주기적으로 새 키 발급
- `.env.local`의 `API_KEY` 값만 변경
- 코드 수정 불필요, 서버 재시작만 필요

### Git 보안
- `.env.local`은 절대 커밋 금지
- `.env.example`만 템플릿으로 커밋
- `.gitignore`에 `.env.local` 포함 확인

### 개발 환경
- 개발 서버 시작 시 API Key 자동 검증
- 콘솔에 검증 상태 출력
- 에러 발생 시 명확한 가이드 제공

---

## 🔍 트러블슈팅

### API Key 에러
```
❌ API_KEY is not configured!
📝 Please check:
   1. .env.local file exists
   2. API_KEY is set correctly
   3. Restart development server (npm run dev)

💡 Contact backend team if you need a new API key.
```

### CORS 에러
- Laravel `config/cors.php` 확인
- `supports_credentials: true` 설정
- `allowed_origins`에 Next.js URL 포함

### 세션 쿠키 안받아짐
- Laravel `SANCTUM_STATEFUL_DOMAINS` 확인
- `localhost:3000` 포함 확인
- `SESSION_DOMAIN` 설정 확인

---

## 📚 참고 문서

- [Laravel Sanctum 공식 문서](https://laravel.com/docs/sanctum)
- [Next.js Middleware 문서](https://nextjs.org/docs/app/building-your-application/routing/middleware)
- [claudedocs/authentication-design.md](./authentication-design.md)
- [claudedocs/api-requirements.md](./api-requirements.md)