mirror of
https://github.com/cna-bootcamp/phonebill.git
synced 2025-12-06 08:06:24 +00:00
820 lines
25 KiB
YAML
820 lines
25 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: Auth Service API
|
|
description: |
|
|
통신요금 관리 서비스의 사용자 인증 및 인가를 담당하는 Auth Service API
|
|
|
|
## 주요 기능
|
|
- 사용자 로그인/로그아웃 처리
|
|
- JWT 토큰 기반 인증
|
|
- Redis를 통한 세션 관리
|
|
- 서비스별 접근 권한 검증
|
|
- 토큰 갱신 처리
|
|
|
|
## 보안 고려사항
|
|
- 5회 연속 로그인 실패 시 30분간 계정 잠금
|
|
- JWT Access Token: 30분 만료
|
|
- JWT Refresh Token: 24시간 만료
|
|
- Redis 세션 캐싱 (TTL: 30분, 자동로그인 시 24시간)
|
|
version: 1.0.0
|
|
contact:
|
|
name: Backend Development Team
|
|
email: backend@mvno.com
|
|
license:
|
|
name: Private
|
|
|
|
servers:
|
|
- url: http://localhost:8081
|
|
description: Development server
|
|
- url: https://api-dev.mvno.com
|
|
description: Development environment
|
|
- url: https://api.mvno.com
|
|
description: Production environment
|
|
|
|
tags:
|
|
- name: Authentication
|
|
description: 사용자 인증 관련 API
|
|
- name: Authorization
|
|
description: 사용자 권한 확인 관련 API
|
|
- name: Token Management
|
|
description: 토큰 관리 관련 API
|
|
- name: Session Management
|
|
description: 세션 관리 관련 API
|
|
|
|
paths:
|
|
/auth/login:
|
|
post:
|
|
tags:
|
|
- Authentication
|
|
summary: 사용자 로그인
|
|
description: |
|
|
MVNO 고객의 로그인을 처리합니다.
|
|
|
|
## 비즈니스 로직
|
|
- UFR-AUTH-010 유저스토리 구현
|
|
- 로그인 시도 횟수 확인 (최대 5회)
|
|
- 비밀번호 검증
|
|
- JWT 토큰 생성 (Access Token: 30분, Refresh Token: 24시간)
|
|
- Redis 세션 생성 및 캐싱
|
|
- 로그인 이력 기록
|
|
|
|
## 보안 정책
|
|
- 5회 연속 실패 시 30분간 계정 잠금
|
|
- 비밀번호 해싱 검증 (bcrypt)
|
|
- IP 기반 로그인 이력 추적
|
|
operationId: login
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/LoginRequest'
|
|
example:
|
|
userId: "mvno001"
|
|
password: "securePassword123!"
|
|
autoLogin: false
|
|
responses:
|
|
'200':
|
|
description: 로그인 성공
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/LoginResponse'
|
|
example:
|
|
success: true
|
|
message: "로그인이 성공적으로 완료되었습니다."
|
|
data:
|
|
accessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
refreshToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
expiresIn: 1800
|
|
user:
|
|
userId: "mvno001"
|
|
userName: "홍길동"
|
|
phoneNumber: "010-1234-5678"
|
|
permissions:
|
|
- "BILL_INQUIRY"
|
|
- "PRODUCT_CHANGE"
|
|
'401':
|
|
description: 인증 실패
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
invalid_credentials:
|
|
summary: 잘못된 인증 정보
|
|
value:
|
|
success: false
|
|
error:
|
|
code: "AUTH_001"
|
|
message: "ID 또는 비밀번호를 확인해주세요"
|
|
details: "입력된 인증 정보가 올바르지 않습니다."
|
|
account_locked:
|
|
summary: 계정 잠금 (5회 실패)
|
|
value:
|
|
success: false
|
|
error:
|
|
code: "AUTH_002"
|
|
message: "5회 연속 실패하여 30분간 계정이 잠금되었습니다."
|
|
details: "30분 후 다시 시도해주세요."
|
|
account_temp_locked:
|
|
summary: 계정 일시 잠금
|
|
value:
|
|
success: false
|
|
error:
|
|
code: "AUTH_003"
|
|
message: "계정이 잠금되었습니다. 30분 후 다시 시도해주세요."
|
|
details: "이전 5회 연속 실패로 인한 임시 잠금 상태입니다."
|
|
'400':
|
|
description: 잘못된 요청
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
success: false
|
|
error:
|
|
code: "VALIDATION_ERROR"
|
|
message: "요청 데이터가 올바르지 않습니다."
|
|
details: "userId는 필수 입력 항목입니다."
|
|
'500':
|
|
description: 서버 내부 오류
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
success: false
|
|
error:
|
|
code: "INTERNAL_SERVER_ERROR"
|
|
message: "서버 내부 오류가 발생했습니다."
|
|
details: "잠시 후 다시 시도해주세요."
|
|
|
|
/auth/logout:
|
|
post:
|
|
tags:
|
|
- Authentication
|
|
summary: 사용자 로그아웃
|
|
description: |
|
|
현재 사용자의 로그아웃을 처리합니다.
|
|
|
|
## 비즈니스 로직
|
|
- Redis 세션 삭제
|
|
- 로그아웃 이력 기록
|
|
- 클라이언트의 토큰 무효화 안내
|
|
operationId: logout
|
|
security:
|
|
- BearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: 로그아웃 성공
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SuccessResponse'
|
|
example:
|
|
success: true
|
|
message: "로그아웃이 성공적으로 완료되었습니다."
|
|
'401':
|
|
description: 인증되지 않은 요청
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
success: false
|
|
error:
|
|
code: "UNAUTHORIZED"
|
|
message: "인증이 필요합니다."
|
|
details: "유효한 토큰이 필요합니다."
|
|
'500':
|
|
description: 서버 내부 오류
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/auth/verify:
|
|
get:
|
|
tags:
|
|
- Token Management
|
|
summary: JWT 토큰 검증
|
|
description: |
|
|
JWT 토큰의 유효성을 검증하고 사용자 정보를 반환합니다.
|
|
|
|
## 비즈니스 로직
|
|
- JWT 토큰 유효성 검사
|
|
- Redis 세션 확인 (Cache-Aside 패턴)
|
|
- 세션 미스 시 DB에서 재조회 후 캐시 갱신
|
|
- 토큰 만료 검사
|
|
operationId: verifyToken
|
|
security:
|
|
- BearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: 토큰 검증 성공
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TokenVerifyResponse'
|
|
example:
|
|
success: true
|
|
message: "토큰이 유효합니다."
|
|
data:
|
|
valid: true
|
|
user:
|
|
userId: "mvno001"
|
|
userName: "홍길동"
|
|
phoneNumber: "010-1234-5678"
|
|
permissions:
|
|
- "BILL_INQUIRY"
|
|
- "PRODUCT_CHANGE"
|
|
expiresIn: 1200
|
|
'401':
|
|
description: 토큰 무효 또는 만료
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
token_expired:
|
|
summary: 토큰 만료
|
|
value:
|
|
success: false
|
|
error:
|
|
code: "TOKEN_EXPIRED"
|
|
message: "토큰이 만료되었습니다."
|
|
details: "새로운 토큰을 발급받아주세요."
|
|
token_invalid:
|
|
summary: 유효하지 않은 토큰
|
|
value:
|
|
success: false
|
|
error:
|
|
code: "TOKEN_INVALID"
|
|
message: "유효하지 않은 토큰입니다."
|
|
details: "올바른 토큰을 제공해주세요."
|
|
'500':
|
|
description: 서버 내부 오류
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/auth/refresh:
|
|
post:
|
|
tags:
|
|
- Token Management
|
|
summary: 토큰 갱신
|
|
description: |
|
|
Refresh Token을 사용하여 새로운 Access Token을 발급합니다.
|
|
|
|
## 비즈니스 로직
|
|
- Refresh Token 유효성 검증
|
|
- 새로운 Access Token 생성 (30분 만료)
|
|
- Redis 세션 갱신
|
|
- 토큰 갱신 이력 기록
|
|
operationId: refreshToken
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RefreshTokenRequest'
|
|
example:
|
|
refreshToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
responses:
|
|
'200':
|
|
description: 토큰 갱신 성공
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RefreshTokenResponse'
|
|
example:
|
|
success: true
|
|
message: "토큰이 성공적으로 갱신되었습니다."
|
|
data:
|
|
accessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
expiresIn: 1800
|
|
'401':
|
|
description: Refresh Token 무효 또는 만료
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
success: false
|
|
error:
|
|
code: "REFRESH_TOKEN_INVALID"
|
|
message: "Refresh Token이 유효하지 않습니다."
|
|
details: "다시 로그인해주세요."
|
|
'500':
|
|
description: 서버 내부 오류
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/auth/permissions:
|
|
get:
|
|
tags:
|
|
- Authorization
|
|
summary: 사용자 권한 조회
|
|
description: |
|
|
현재 사용자의 서비스 접근 권한을 조회합니다.
|
|
|
|
## 비즈니스 로직
|
|
- UFR-AUTH-020 유저스토리 구현
|
|
- 사용자 권한 정보 조회
|
|
- 서비스별 접근 권한 확인
|
|
- Redis 캐시 우선 조회 (Cache-Aside 패턴)
|
|
operationId: getUserPermissions
|
|
security:
|
|
- BearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: 권한 조회 성공
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PermissionsResponse'
|
|
example:
|
|
success: true
|
|
message: "권한 정보를 성공적으로 조회했습니다."
|
|
data:
|
|
userId: "mvno001"
|
|
permissions:
|
|
- permission: "BILL_INQUIRY"
|
|
description: "요금 조회 서비스"
|
|
granted: true
|
|
- permission: "PRODUCT_CHANGE"
|
|
description: "상품 변경 서비스"
|
|
granted: true
|
|
'401':
|
|
description: 인증되지 않은 요청
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'500':
|
|
description: 서버 내부 오류
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/auth/permissions/check:
|
|
post:
|
|
tags:
|
|
- Authorization
|
|
summary: 특정 서비스 접근 권한 확인
|
|
description: |
|
|
사용자가 특정 서비스에 접근할 권한이 있는지 확인합니다.
|
|
|
|
## 비즈니스 로직
|
|
- 서비스별 접근 권한 검증
|
|
- BILL_INQUIRY: 요금 조회 서비스 권한
|
|
- PRODUCT_CHANGE: 상품 변경 서비스 권한
|
|
- Redis 세션 데이터 기반 권한 확인
|
|
operationId: checkPermission
|
|
security:
|
|
- BearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PermissionCheckRequest'
|
|
example:
|
|
serviceType: "BILL_INQUIRY"
|
|
responses:
|
|
'200':
|
|
description: 권한 확인 완료
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PermissionCheckResponse'
|
|
examples:
|
|
permission_granted:
|
|
summary: 권한 있음
|
|
value:
|
|
success: true
|
|
message: "서비스 접근 권한이 확인되었습니다."
|
|
data:
|
|
serviceType: "BILL_INQUIRY"
|
|
hasPermission: true
|
|
permissionDetails:
|
|
permission: "BILL_INQUIRY"
|
|
description: "요금 조회 서비스"
|
|
granted: true
|
|
permission_denied:
|
|
summary: 권한 없음
|
|
value:
|
|
success: true
|
|
message: "서비스 접근 권한이 없습니다."
|
|
data:
|
|
serviceType: "BILL_INQUIRY"
|
|
hasPermission: false
|
|
permissionDetails:
|
|
permission: "BILL_INQUIRY"
|
|
description: "요금 조회 서비스"
|
|
granted: false
|
|
'400':
|
|
description: 잘못된 요청
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
success: false
|
|
error:
|
|
code: "VALIDATION_ERROR"
|
|
message: "serviceType은 필수 입력 항목입니다."
|
|
details: "BILL_INQUIRY 또는 PRODUCT_CHANGE 값을 입력해주세요."
|
|
'401':
|
|
description: 인증되지 않은 요청
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'500':
|
|
description: 서버 내부 오류
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/auth/user-info:
|
|
get:
|
|
tags:
|
|
- Session Management
|
|
summary: 사용자 정보 조회
|
|
description: |
|
|
현재 인증된 사용자의 상세 정보를 조회합니다.
|
|
|
|
## 비즈니스 로직
|
|
- JWT 토큰에서 사용자 식별
|
|
- Redis 세션 우선 조회
|
|
- 캐시 미스 시 DB 조회 후 캐시 갱신
|
|
- 사용자 기본 정보 및 권한 정보 반환
|
|
operationId: getUserInfo
|
|
security:
|
|
- BearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: 사용자 정보 조회 성공
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/UserInfoResponse'
|
|
example:
|
|
success: true
|
|
message: "사용자 정보를 성공적으로 조회했습니다."
|
|
data:
|
|
userId: "mvno001"
|
|
userName: "홍길동"
|
|
phoneNumber: "010-1234-5678"
|
|
email: "hong@example.com"
|
|
status: "ACTIVE"
|
|
lastLoginAt: "2024-01-15T09:30:00Z"
|
|
permissions:
|
|
- "BILL_INQUIRY"
|
|
- "PRODUCT_CHANGE"
|
|
'401':
|
|
description: 인증되지 않은 요청
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'404':
|
|
description: 사용자 정보 없음
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
success: false
|
|
error:
|
|
code: "USER_NOT_FOUND"
|
|
message: "사용자 정보를 찾을 수 없습니다."
|
|
details: "해당 사용자가 존재하지 않습니다."
|
|
'500':
|
|
description: 서버 내부 오류
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
components:
|
|
securitySchemes:
|
|
BearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
description: "JWT 토큰을 Authorization 헤더에 포함해주세요. (예: Bearer eyJhbGciOiJIUzI1NiIs...)"
|
|
|
|
schemas:
|
|
# Request Schemas
|
|
LoginRequest:
|
|
type: object
|
|
required:
|
|
- userId
|
|
- password
|
|
properties:
|
|
userId:
|
|
type: string
|
|
description: 사용자 ID (고객 식별자)
|
|
minLength: 3
|
|
maxLength: 20
|
|
pattern: '^[a-zA-Z0-9_-]+$'
|
|
example: "mvno001"
|
|
password:
|
|
type: string
|
|
description: 사용자 비밀번호
|
|
format: password
|
|
minLength: 8
|
|
maxLength: 50
|
|
example: "securePassword123!"
|
|
autoLogin:
|
|
type: boolean
|
|
description: 자동 로그인 옵션 (true 시 24시간 세션 유지)
|
|
default: false
|
|
example: false
|
|
|
|
RefreshTokenRequest:
|
|
type: object
|
|
required:
|
|
- refreshToken
|
|
properties:
|
|
refreshToken:
|
|
type: string
|
|
description: JWT Refresh Token
|
|
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
|
|
PermissionCheckRequest:
|
|
type: object
|
|
required:
|
|
- serviceType
|
|
properties:
|
|
serviceType:
|
|
type: string
|
|
description: 확인하려는 서비스 타입
|
|
enum:
|
|
- BILL_INQUIRY
|
|
- PRODUCT_CHANGE
|
|
example: "BILL_INQUIRY"
|
|
|
|
# Response Schemas
|
|
LoginResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
description: 응답 성공 여부
|
|
example: true
|
|
message:
|
|
type: string
|
|
description: 응답 메시지
|
|
example: "로그인이 성공적으로 완료되었습니다."
|
|
data:
|
|
type: object
|
|
properties:
|
|
accessToken:
|
|
type: string
|
|
description: JWT Access Token (30분 만료)
|
|
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
refreshToken:
|
|
type: string
|
|
description: JWT Refresh Token (24시간 만료)
|
|
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
expiresIn:
|
|
type: integer
|
|
description: Access Token 만료까지 남은 시간 (초)
|
|
example: 1800
|
|
user:
|
|
$ref: '#/components/schemas/UserInfo'
|
|
|
|
TokenVerifyResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
message:
|
|
type: string
|
|
example: "토큰이 유효합니다."
|
|
data:
|
|
type: object
|
|
properties:
|
|
valid:
|
|
type: boolean
|
|
description: 토큰 유효성
|
|
example: true
|
|
user:
|
|
$ref: '#/components/schemas/UserInfo'
|
|
expiresIn:
|
|
type: integer
|
|
description: 토큰 만료까지 남은 시간 (초)
|
|
example: 1200
|
|
|
|
RefreshTokenResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
message:
|
|
type: string
|
|
example: "토큰이 성공적으로 갱신되었습니다."
|
|
data:
|
|
type: object
|
|
properties:
|
|
accessToken:
|
|
type: string
|
|
description: 새로 발급된 JWT Access Token
|
|
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
expiresIn:
|
|
type: integer
|
|
description: 새 토큰 만료까지 남은 시간 (초)
|
|
example: 1800
|
|
|
|
PermissionsResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
message:
|
|
type: string
|
|
example: "권한 정보를 성공적으로 조회했습니다."
|
|
data:
|
|
type: object
|
|
properties:
|
|
userId:
|
|
type: string
|
|
example: "mvno001"
|
|
permissions:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Permission'
|
|
|
|
PermissionCheckResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
message:
|
|
type: string
|
|
example: "서비스 접근 권한이 확인되었습니다."
|
|
data:
|
|
type: object
|
|
properties:
|
|
serviceType:
|
|
type: string
|
|
example: "BILL_INQUIRY"
|
|
hasPermission:
|
|
type: boolean
|
|
example: true
|
|
permissionDetails:
|
|
$ref: '#/components/schemas/Permission'
|
|
|
|
UserInfoResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
message:
|
|
type: string
|
|
example: "사용자 정보를 성공적으로 조회했습니다."
|
|
data:
|
|
$ref: '#/components/schemas/UserInfoDetail'
|
|
|
|
SuccessResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
message:
|
|
type: string
|
|
example: "요청이 성공적으로 처리되었습니다."
|
|
|
|
ErrorResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: false
|
|
error:
|
|
type: object
|
|
properties:
|
|
code:
|
|
type: string
|
|
description: 오류 코드
|
|
example: "AUTH_001"
|
|
message:
|
|
type: string
|
|
description: 사용자에게 표시될 오류 메시지
|
|
example: "ID 또는 비밀번호를 확인해주세요"
|
|
details:
|
|
type: string
|
|
description: 상세 오류 정보
|
|
example: "입력된 인증 정보가 올바르지 않습니다."
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
description: 오류 발생 시간
|
|
example: "2024-01-15T10:30:00Z"
|
|
|
|
# Common Schemas
|
|
UserInfo:
|
|
type: object
|
|
properties:
|
|
userId:
|
|
type: string
|
|
description: 사용자 ID
|
|
example: "mvno001"
|
|
userName:
|
|
type: string
|
|
description: 사용자 이름
|
|
example: "홍길동"
|
|
phoneNumber:
|
|
type: string
|
|
description: 휴대폰 번호
|
|
example: "010-1234-5678"
|
|
permissions:
|
|
type: array
|
|
description: 사용자 권한 목록
|
|
items:
|
|
type: string
|
|
enum:
|
|
- BILL_INQUIRY
|
|
- PRODUCT_CHANGE
|
|
example:
|
|
- "BILL_INQUIRY"
|
|
- "PRODUCT_CHANGE"
|
|
|
|
UserInfoDetail:
|
|
type: object
|
|
properties:
|
|
userId:
|
|
type: string
|
|
example: "mvno001"
|
|
userName:
|
|
type: string
|
|
example: "홍길동"
|
|
phoneNumber:
|
|
type: string
|
|
example: "010-1234-5678"
|
|
email:
|
|
type: string
|
|
format: email
|
|
example: "hong@example.com"
|
|
status:
|
|
type: string
|
|
enum:
|
|
- ACTIVE
|
|
- INACTIVE
|
|
- LOCKED
|
|
example: "ACTIVE"
|
|
lastLoginAt:
|
|
type: string
|
|
format: date-time
|
|
description: 마지막 로그인 시간
|
|
example: "2024-01-15T09:30:00Z"
|
|
permissions:
|
|
type: array
|
|
items:
|
|
type: string
|
|
example:
|
|
- "BILL_INQUIRY"
|
|
- "PRODUCT_CHANGE"
|
|
|
|
Permission:
|
|
type: object
|
|
properties:
|
|
permission:
|
|
type: string
|
|
enum:
|
|
- BILL_INQUIRY
|
|
- PRODUCT_CHANGE
|
|
example: "BILL_INQUIRY"
|
|
description:
|
|
type: string
|
|
example: "요금 조회 서비스"
|
|
granted:
|
|
type: boolean
|
|
example: true
|
|
|
|
# API 오류 코드 정의
|
|
# AUTH_001: 잘못된 인증 정보
|
|
# AUTH_002: 계정 잠금 (5회 실패)
|
|
# AUTH_003: 계정 일시 잠금
|
|
# TOKEN_EXPIRED: 토큰 만료
|
|
# TOKEN_INVALID: 유효하지 않은 토큰
|
|
# REFRESH_TOKEN_INVALID: Refresh Token 무효
|
|
# USER_NOT_FOUND: 사용자 정보 없음
|
|
# UNAUTHORIZED: 인증 필요
|
|
# VALIDATION_ERROR: 입력 데이터 검증 오류
|
|
# INTERNAL_SERVER_ERROR: 서버 내부 오류 |