Files
works/oauth/docs/api-specification.md
Claude f53d55e712 Initial commit: OAuth 2.0 인증 시스템 with APISIX API Gateway
- FastAPI 백엔드 + MongoDB + Redis 구성
- React + Vite + TypeScript + shadcn/ui 프론트엔드
- Apache APISIX API Gateway 통합
- Docker Compose 기반 개발 환경
- 3단계 권한 체계 (System Admin, Group Admin, User)
- 동적 테마 지원
- 환경별 설정 (dev/vei/prod)

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-31 10:16:41 +09:00

6.0 KiB

OAuth API 명세서

Base URL

  • Development: http://localhost:8000/api/v1
  • Verification: https://vei-oauth-api.example.com/api/v1
  • Production: https://api-oauth.example.com/api/v1

인증 헤더

Authorization: Bearer {access_token}

API 엔드포인트

인증 (Authentication)

POST /auth/login

사용자 로그인

Request Body:

{
  "email": "user@example.com",
  "password": "password123"
}

Response:

{
  "access_token": "eyJ...",
  "refresh_token": "eyJ...",
  "token_type": "bearer",
  "expires_in": 1800
}

POST /auth/logout

사용자 로그아웃

Headers:

  • Authorization: Bearer {access_token}

Response:

{
  "message": "Successfully logged out"
}

POST /auth/refresh

토큰 갱신

Request Body:

{
  "refresh_token": "eyJ..."
}

Response:

{
  "access_token": "eyJ...",
  "token_type": "bearer",
  "expires_in": 1800
}

POST /auth/authorize

OAuth 인증 요청

Query Parameters:

  • response_type: "code"
  • client_id: Application Client ID
  • redirect_uri: Redirect URI
  • scope: 요청 권한 (space 구분)
  • state: CSRF 방지용 상태값

Response:

  • 302 Redirect to {redirect_uri}?code={auth_code}&state={state}

POST /auth/token

Access Token 발급

Request Body:

{
  "grant_type": "authorization_code",
  "code": "auth_code",
  "client_id": "client_id",
  "client_secret": "client_secret",
  "redirect_uri": "redirect_uri"
}

Response:

{
  "access_token": "eyJ...",
  "refresh_token": "eyJ...",
  "token_type": "bearer",
  "expires_in": 1800,
  "scope": "read write"
}

사용자 관리 (Users)

GET /users/me

현재 사용자 정보 조회

Response:

{
  "id": "user_id",
  "email": "user@example.com",
  "username": "username",
  "full_name": "John Doe",
  "role": "user",
  "profile_picture": "https://...",
  "created_at": "2024-01-01T00:00:00Z",
  "last_login": "2024-01-01T00:00:00Z"
}

PUT /users/me

사용자 정보 수정

Request Body:

{
  "full_name": "Jane Doe",
  "phone_number": "+1234567890",
  "birth_date": "1990-01-01",
  "gender": "female"
}

POST /users/me/password

패스워드 변경

Request Body:

{
  "current_password": "old_password",
  "new_password": "new_password"
}

POST /users/me/profile-picture

프로필 사진 업로드

Request:

  • Content-Type: multipart/form-data
  • File: image file

GET /users/me/permissions

사용자 권한 조회

Response:

{
  "single_sign_on": true,
  "share_name": true,
  "share_gender": false,
  "share_birth_date": false,
  "share_email": true,
  "share_phone": false
}

PUT /users/me/permissions

사용자 권한 수정

Request Body:

{
  "share_gender": true,
  "share_birth_date": true
}

GET /users/me/applications

인증된 애플리케이션 목록

Response:

{
  "applications": [
    {
      "id": "app_id",
      "name": "Application Name",
      "logo_url": "https://...",
      "authorized_at": "2024-01-01T00:00:00Z",
      "last_used": "2024-01-01T00:00:00Z",
      "permissions": ["read", "write"]
    }
  ]
}

DELETE /users/me/applications/{app_id}

애플리케이션 인증 해제

애플리케이션 관리 (Applications)

GET /applications

애플리케이션 목록 조회 (Admin only)

POST /applications

애플리케이션 등록 (Admin only)

Request Body:

{
  "app_name": "My Application",
  "description": "Application description",
  "redirect_uris": ["https://app.example.com/callback"],
  "allowed_origins": ["https://app.example.com"],
  "theme": {
    "primary_color": "#1976d2",
    "secondary_color": "#dc004e",
    "logo_url": "https://...",
    "background_image_url": "https://..."
  }
}

Response:

{
  "id": "app_id",
  "client_id": "generated_client_id",
  "client_secret": "generated_client_secret",
  "app_name": "My Application",
  "created_at": "2024-01-01T00:00:00Z"
}

GET /applications/{app_id}

애플리케이션 상세 조회

PUT /applications/{app_id}

애플리케이션 수정 (Admin only)

DELETE /applications/{app_id}

애플리케이션 삭제 (Admin only)

POST /applications/{app_id}/regenerate-secret

Client Secret 재생성 (Admin only)

관리자 (Admin)

GET /admin/users

전체 사용자 목록 (System Admin only)

Query Parameters:

  • page: 페이지 번호 (default: 1)
  • limit: 페이지당 항목 수 (default: 20)
  • role: 역할 필터
  • search: 검색어

GET /admin/users/{user_id}

사용자 상세 조회 (Admin only)

PUT /admin/users/{user_id}/role

사용자 역할 변경 (System Admin only)

Request Body:

{
  "role": "group_admin"
}

GET /admin/audit-logs

감사 로그 조회 (Admin only)

Query Parameters:

  • user_id: 사용자 ID
  • app_id: 애플리케이션 ID
  • action: 액션 타입
  • start_date: 시작일
  • end_date: 종료일

GET /admin/statistics

통계 정보 조회 (Admin only)

Response:

{
  "total_users": 1000,
  "active_users_today": 150,
  "total_applications": 25,
  "total_authentications_today": 5000,
  "top_applications": [...]
}

에러 응답

에러 응답 형식

{
  "error": "error_code",
  "message": "Error message",
  "details": {}
}

에러 코드

  • 400: Bad Request
  • 401: Unauthorized
  • 403: Forbidden
  • 404: Not Found
  • 409: Conflict
  • 422: Unprocessable Entity
  • 429: Too Many Requests
  • 500: Internal Server Error

Rate Limiting

  • 일반 API: 100 requests/minute
  • 인증 API: 10 requests/minute
  • 관리자 API: 1000 requests/minute

Webhooks

이벤트 타입

  • user.created
  • user.updated
  • user.deleted
  • user.login
  • user.logout
  • application.authorized
  • application.revoked

Webhook 페이로드

{
  "event": "user.login",
  "timestamp": "2024-01-01T00:00:00Z",
  "data": {
    "user_id": "user_id",
    "application_id": "app_id",
    "ip_address": "192.168.1.1"
  }
}