- BOM 항목 추가/수정/삭제 시 섹션탭 즉시 반영 - 섹션 복제 시 UI 즉시 업데이트 (null vs undefined 이슈 해결) - 항목 수정 기능 추가 (useTemplateManagement) - 실시간 동기화 문서 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
328 lines
7.5 KiB
Markdown
328 lines
7.5 KiB
Markdown
# 인증 시스템 구현 가이드
|
||
|
||
## 📋 개요
|
||
|
||
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)
|
||
|
||
---
|
||
|
||
## 관련 파일
|
||
|
||
### 프론트엔드
|
||
- `src/lib/api/client.ts` - 통합 HTTP Client
|
||
- `src/lib/api/auth/types.ts` - 인증 타입 정의
|
||
- `src/lib/api/auth/auth-config.ts` - 인증 설정
|
||
- `src/lib/api/auth/sanctum-client.ts` - Sanctum 전용 클라이언트
|
||
- `src/lib/api/auth/bearer-client.ts` - Bearer 토큰 클라이언트
|
||
- `src/lib/api/auth/api-key-client.ts` - API Key 클라이언트
|
||
- `src/contexts/AuthContext.tsx` - 클라이언트 인증 상태 관리
|
||
- `src/middleware.ts` - 통합 미들웨어
|
||
|
||
### 설정 파일
|
||
- `.env.local` - 환경 변수
|
||
- `.env.example` - 환경 변수 템플릿 |