# 카카오 소셜 로그인 구현 가이드

## 목차

1. [개요](#1-개요)
2. [인증 흐름](#2-인증-흐름)
3. [User 모델 구조](#3-user-모델-구조)
4. [API 엔드포인트](#4-api-엔드포인트)
5. [환경 설정](#5-환경-설정)
6. [에러 처리](#6-에러-처리)

---

## 1. 개요

CastAD는 카카오 소셜 로그인만 지원하며, 인증 후 자체 JWT 토큰을 발급합니다.

### 인증 방식

| 항목 | 설명 |
|------|------|
| 소셜 로그인 | 카카오 OAuth 2.0 |
| 자체 인증 | JWT (Access Token + Refresh Token) |
| 카카오 토큰 저장 | X (1회 검증 후 폐기) |

---

## 2. 인증 흐름

### 2.1 전체 흐름도

```
┌─────────┐     ┌─────────┐     ┌─────────┐     ┌─────────┐
│ Client  │     │ Backend │     │  Kakao  │     │   DB    │
└────┬────┘     └────┬────┘     └────┬────┘     └────┬────┘
     │               │               │               │
     │ 1. 로그인 요청 │               │               │
     │──────────────>│               │               │
     │               │               │               │
     │ 2. 카카오 로그인 URL 반환       │               │
     │<──────────────│               │               │
     │               │               │               │
     │ 3. 카카오 로그인 페이지로 이동   │               │
     │──────────────────────────────>│               │
     │               │               │               │
     │ 4. 사용자 인증 후 code 반환     │               │
     │<──────────────────────────────│               │
     │               │               │               │
     │ 5. code 전달   │               │               │
     │──────────────>│               │               │
     │               │               │               │
     │               │ 6. code로 토큰 요청             │
     │               │──────────────>│               │
     │               │               │               │
     │               │ 7. access_token 반환           │
     │               │<──────────────│               │
     │               │               │               │
     │               │ 8. 사용자 정보 조회             │
     │               │──────────────>│               │
     │               │               │               │
     │               │ 9. 사용자 정보 반환             │
     │               │<──────────────│               │
     │               │               │               │
     │               │ 10. kakao_id로 회원 조회       │
     │               │──────────────────────────────>│
     │               │               │               │
     │               │ 11. 회원 정보 반환 (없으면 생성) │
     │               │<──────────────────────────────│
     │               │               │               │
     │ 12. 자체 JWT 발급 및 반환       │               │
     │<──────────────│               │               │
     │               │               │               │
```

### 2.2 단계별 설명

| 단계 | 설명 | 관련 API |
|------|------|----------|
| 1-2 | 클라이언트가 로그인 요청, 백엔드가 카카오 인증 URL 생성 | `GET /user/auth/kakao/login` |
| 3-4 | 사용자가 카카오에서 로그인, 인가 코드(code) 발급 | 카카오 OAuth |
| 5-9 | 백엔드가 code로 카카오 토큰/사용자정보 획득 | 카카오 API |
| 10-11 | DB에서 회원 조회, 없으면 신규 가입 | 내부 처리 |
| 12 | 자체 JWT 토큰 발급 후 클라이언트에 반환 | `POST /user/auth/kakao/callback` |

---

## 3. User 모델 구조

### 3.1 테이블 스키마

```
┌─────────────────────────────────────────────────────────────┐
│                          user                                │
├─────────────────────┬───────────────┬───────────────────────┤
│ Column              │ Type          │ Description           │
├─────────────────────┼───────────────┼───────────────────────┤
│ id                  │ BIGINT (PK)   │ 고유 식별자 (자동증가)  │
│ kakao_id            │ BIGINT (UQ)   │ 카카오 회원번호         │
│ email               │ VARCHAR(255)  │ 이메일 (선택)          │
│ nickname            │ VARCHAR(100)  │ 닉네임 (선택)          │
│ profile_image_url   │ VARCHAR(2048) │ 프로필 이미지 URL      │
│ thumbnail_image_url │ VARCHAR(2048) │ 썸네일 이미지 URL      │
│ is_active           │ BOOLEAN       │ 계정 활성화 상태        │
│ is_admin            │ BOOLEAN       │ 관리자 권한            │
│ last_login_at       │ DATETIME      │ 마지막 로그인 일시      │
│ created_at          │ DATETIME      │ 생성 일시              │
│ updated_at          │ DATETIME      │ 수정 일시              │
└─────────────────────┴───────────────┴───────────────────────┘
```

### 3.2 카카오 API 응답 매핑

```json
// 카카오 API 응답 예시
{
  "id": 1234567890,
  "kakao_account": {
    "email": "user@kakao.com",
    "profile": {
      "nickname": "홍길동",
      "profile_image_url": "https://k.kakaocdn.net/.../profile.jpg",
      "thumbnail_image_url": "https://k.kakaocdn.net/.../thumb.jpg"
    }
  }
}
```

| User 필드 | 카카오 응답 경로 |
|-----------|-----------------|
| `kakao_id` | `id` |
| `email` | `kakao_account.email` |
| `nickname` | `kakao_account.profile.nickname` |
| `profile_image_url` | `kakao_account.profile.profile_image_url` |
| `thumbnail_image_url` | `kakao_account.profile.thumbnail_image_url` |

---

## 4. API 엔드포인트

### 4.1 카카오 로그인 URL 요청

```
GET /user/auth/kakao/login
```

**Response:**
```json
{
  "auth_url": "https://kauth.kakao.com/oauth/authorize?client_id=...&redirect_uri=...&response_type=code"
}
```

### 4.2 카카오 콜백 (로그인/가입 처리)

```
POST /user/auth/kakao/callback
```

**Request:**
```json
{
  "code": "인가코드"
}
```

**Response (성공):**
```json
{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "user": {
    "id": 1,
    "nickname": "홍길동",
    "email": "user@kakao.com",
    "profile_image_url": "https://...",
    "is_new_user": false
  }
}
```

### 4.3 토큰 갱신

```
POST /user/auth/refresh
```

**Request:**
```json
{
  "refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}
```

**Response:**
```json
{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600
}
```

### 4.4 로그아웃

```
POST /user/auth/logout
Authorization: Bearer {access_token}
```

### 4.5 모든 기기에서 로그아웃

```
POST /user/auth/logout/all
Authorization: Bearer {access_token}
```

### 4.6 내 정보 조회

```
GET /user/auth/me
Authorization: Bearer {access_token}
```

**Response:**
```json
{
  "id": 1,
  "kakao_id": 1234567890,
  "nickname": "홍길동",
  "email": "user@kakao.com",
  "profile_image_url": "https://...",
  "is_admin": false,
  "created_at": "2026-01-14T16:00:00"
}
```

---

## 5. 환경 설정

### 5.1 카카오 개발자 설정

1. [카카오 개발자 콘솔](https://developers.kakao.com) 접속
2. 애플리케이션 생성
3. 플랫폼 > Web 사이트 도메인 등록
4. 카카오 로그인 > Redirect URI 등록
5. 동의항목 > 필요한 정보 설정

### 5.2 .env 설정

```env
# 카카오 OAuth
KAKAO_CLIENT_ID=your_rest_api_key
KAKAO_CLIENT_SECRET=your_client_secret  # 선택
KAKAO_REDIRECT_URI=https://your-domain.com/api/v1/auth/kakao/callback

# JWT
JWT_SECRET=your-super-secret-key-min-32-characters
JWT_ALGORITHM=HS256
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=60
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
```

### 5.3 config.py 설정

```python
class KakaoSettings(BaseSettings):
    KAKAO_CLIENT_ID: str = Field(...)
    KAKAO_CLIENT_SECRET: str = Field(default="")
    KAKAO_REDIRECT_URI: str = Field(...)

    model_config = _base_config


class JWTSettings(BaseSettings):
    JWT_SECRET: str = Field(...)
    JWT_ALGORITHM: str = Field(default="HS256")
    JWT_ACCESS_TOKEN_EXPIRE_MINUTES: int = Field(default=60)
    JWT_REFRESH_TOKEN_EXPIRE_DAYS: int = Field(default=7)

    model_config = _base_config
```

---

## 6. 에러 처리

### 6.1 에러 코드 정의

| HTTP Status | Error Code | 설명 |
|-------------|------------|------|
| 400 | `INVALID_CODE` | 유효하지 않은 인가 코드 |
| 400 | `KAKAO_AUTH_FAILED` | 카카오 인증 실패 |
| 401 | `TOKEN_EXPIRED` | 토큰 만료 |
| 401 | `INVALID_TOKEN` | 유효하지 않은 토큰 |
| 401 | `TOKEN_REVOKED` | 취소된 토큰 |
| 403 | `USER_INACTIVE` | 비활성화된 계정 |
| 403 | `ADMIN_REQUIRED` | 관리자 권한 필요 |
| 404 | `USER_NOT_FOUND` | 사용자 없음 |
| 500 | `KAKAO_API_ERROR` | 카카오 API 오류 |

### 6.2 에러 응답 형식

```json
{
  "detail": {
    "code": "TOKEN_EXPIRED",
    "message": "토큰이 만료되었습니다. 다시 로그인해주세요."
  }
}
```

---

## 부록: 파일 구조

```
app/user/
├── __init__.py
├── models.py              # User, RefreshToken 모델
├── exceptions.py          # 사용자 정의 예외
├── schemas/
│   ├── __init__.py
│   └── user_schema.py     # Pydantic 스키마
├── services/
│   ├── __init__.py
│   ├── auth.py            # 인증 서비스
│   ├── jwt.py             # JWT 유틸리티
│   └── kakao.py           # 카카오 OAuth 클라이언트
├── dependencies/
│   ├── __init__.py
│   └── auth.py            # 인증 의존성 (get_current_user 등)
└── api/
    └── routers/
        └── v1/
            ├── __init__.py
            └── auth.py    # 인증 API 라우터
```
