본문으로 건너뛰기

Auth — /api/auth/*

회원가입 + JWT access/refresh 발급 + 갱신 + 사용자 프로필 조회 라우트입니다.

공통

  • 베이스 경로: /api/auth
  • 인증: register/login/refresh는 인증 불필요. me는 access 토큰 필요.
  • 비밀번호: bcrypt 해시 저장. 평문은 절대 응답에 포함되지 않음.

POST /api/auth/register

신규 사용자 등록.

요청 (UserRegister)

필드타입필수설명
usernamestring (3–64, ^[a-zA-Z0-9_]+$)Y영숫자 + 언더스코어
emailEmailStrYRFC 5322
passwordstring (8–128)Y평문 (서버에서 해시)

응답 201 (UserResponse)

{
"id": 42,
"username": "alice",
"email": "alice@example.com",
"role": "user",
"is_active": true,
"created_at": "2026-04-26T10:00:00Z"
}

에러

  • 409 — username/email 중복

cURL

curl -X POST http://localhost:8000/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"username": "alice",
"email": "alice@example.com",
"password": "S3cure!Passw0rd"
}'

TypeScript

import { api } from '@/api/client';

const user = await api.post<UserResponse>('/api/auth/register', {
username: 'alice',
email: 'alice@example.com',
password: 'S3cure!Passw0rd',
});

POST /api/auth/login

비밀번호로 로그인하고 access + refresh 토큰을 받습니다.

요청 (UserLogin)

필드타입필수
usernamestringY
passwordstringY

응답 200 (TokenResponse)

{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "bearer"
}
  • access_token: 기본 30분 유효 (AUTH_ACCESS_TOKEN_TTL_MIN)
  • refresh_token: 기본 7일 유효 (AUTH_REFRESH_TOKEN_TTL_DAYS)

에러

  • 401 — 비밀번호 불일치 / 사용자 없음
  • 403 — 계정 비활성화

cURL

curl -X POST http://localhost:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"alice","password":"S3cure!Passw0rd"}'

POST /api/auth/refresh

만료된 access 토큰을 refresh 토큰으로 재발급합니다.

요청 (TokenRefresh)

필드타입필수
refresh_tokenstringY

응답 200 (TokenResponse)

새 access + refresh 토큰을 함께 반환합니다 (refresh rotation).

에러

  • 401 — 만료/무효 refresh 토큰

cURL

curl -X POST http://localhost:8000/api/auth/refresh \
-H "Content-Type: application/json" \
-d '{"refresh_token":"eyJhbGciOiJIUzI1NiIs..."}'

GET /api/auth/me

현재 access 토큰의 사용자 프로필을 반환합니다.

인증

Authorization: Bearer <access_token>

응답 200 (UserResponse)

register 응답과 동일.

에러

  • 401 — 토큰 누락/만료/무효

cURL

curl -H "Authorization: Bearer $JWT" \
http://localhost:8000/api/auth/me

TypeScript

const me = await api.get<UserResponse>('/api/auth/me', {
headers: { Authorization: `Bearer ${jwt}` },
});

멀티유저 격리

  • 모든 인증된 라우트는 current_user.id를 기준으로 데이터 필터링
  • 토큰 payload의 sub (user_id)는 변조 시 401
  • 토큰 payload의 typeaccess/refresh 중 하나여야 함 (잘못된 type 사용 시 401)

비고

  • AUTH_SECRET_KEY 변경 시 모든 발급된 JWT가 무효화됩니다 (서비스 재시작 시 강제 재로그인 발생).
  • 비밀번호 정책은 password 필드의 길이 제약 외에는 적용되지 않으며, 강력한 정책이 필요하면 클라이언트 측에서 추가 검증하세요.