o2o-castad-backend/docs/user/kakao.md

11 KiB

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

목차

  1. 개요
  2. 인증 흐름
  3. User 모델 구조
  4. API 엔드포인트
  5. 환경 설정
  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 /api/v1/auth/kakao/login
3-4 사용자가 카카오에서 로그인, 인가 코드(code) 발급 카카오 OAuth
5-9 백엔드가 code로 카카오 토큰/사용자정보 획득 카카오 API
10-11 DB에서 회원 조회, 없으면 신규 가입 내부 처리
12 자체 JWT 토큰 발급 후 클라이언트에 반환 POST /api/v1/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 응답 매핑

// 카카오 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 /api/v1/auth/kakao/login

Response:

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

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

POST /api/v1/auth/kakao/callback

Request:

{
  "code": "인가코드"
}

Response (성공):

{
  "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 /api/v1/auth/refresh

Request:

{
  "refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600
}

4.4 로그아웃

POST /api/v1/auth/logout
Authorization: Bearer {access_token}

4.5 내 정보 조회

GET /api/v1/users/me
Authorization: Bearer {access_token}

Response:

{
  "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. 카카오 개발자 콘솔 접속
  2. 애플리케이션 생성
  3. 플랫폼 > Web 사이트 도메인 등록
  4. 카카오 로그인 > Redirect URI 등록
  5. 동의항목 > 필요한 정보 설정

5.2 .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 설정

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 에러 응답 형식

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

부록: 파일 구조

app/user/
├── __init__.py
├── models.py              # User 모델
├── schemas/
│   ├── __init__.py
│   └── user_schema.py     # Pydantic 스키마
├── services/
│   ├── __init__.py
│   ├── auth.py            # 인증 서비스
│   ├── jwt.py             # JWT 서비스
│   └── kakao.py           # 카카오 OAuth 서비스
├── api/
│   ├── __init__.py
│   └── routers/
│       └── v1/
│           ├── __init__.py
│           └── auth.py    # 인증 API 라우터
└── exceptions.py          # 사용자 정의 예외