102 lines
3.2 KiB
Python
102 lines
3.2 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
|
from sqlalchemy.orm import Session
|
|
from app.database import get_db
|
|
from app.schemas.auth import UserRegister, UserLogin, Token, UserResponse, CurrentUser
|
|
from app.services.auth_service import auth_service
|
|
from app.utils.jwt_handler import decode_token
|
|
from app.utils.exceptions import AuthenticationError
|
|
|
|
router = APIRouter()
|
|
security = HTTPBearer()
|
|
|
|
# 현재 사용자 가져오기 의존성
|
|
async def get_current_user(
|
|
credentials: HTTPAuthorizationCredentials = Depends(security),
|
|
db: Session = Depends(get_db)
|
|
) -> CurrentUser:
|
|
"""JWT 토큰에서 현재 사용자 정보 추출"""
|
|
token = credentials.credentials
|
|
payload = decode_token(token)
|
|
|
|
if not payload:
|
|
raise AuthenticationError("유효하지 않은 토큰입니다")
|
|
|
|
user_id = payload.get("sub")
|
|
if not user_id:
|
|
raise AuthenticationError("토큰 정보가 올바르지 않습니다")
|
|
|
|
user = auth_service.get_user_by_id(db, int(user_id))
|
|
if not user:
|
|
raise AuthenticationError("사용자를 찾을 수 없습니다")
|
|
|
|
if not user.is_active:
|
|
raise AuthenticationError("비활성화된 계정입니다")
|
|
|
|
return CurrentUser(
|
|
id=user.id,
|
|
username=user.username,
|
|
email=user.email,
|
|
role=user.role,
|
|
is_active=user.is_active
|
|
)
|
|
|
|
@router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
|
|
async def register(user_data: UserRegister, db: Session = Depends(get_db)):
|
|
"""
|
|
회원가입
|
|
|
|
새로운 사용자 계정을 생성합니다.
|
|
"""
|
|
user = auth_service.register_user(db, user_data)
|
|
return user
|
|
|
|
@router.post("/login", response_model=Token)
|
|
async def login(login_data: UserLogin, db: Session = Depends(get_db)):
|
|
"""
|
|
로그인
|
|
|
|
사용자 인증 후 JWT 토큰을 발급합니다.
|
|
"""
|
|
user = auth_service.authenticate_user(db, login_data.username, login_data.password)
|
|
tokens = auth_service.create_tokens(user)
|
|
return tokens
|
|
|
|
@router.get("/me", response_model=UserResponse)
|
|
async def get_me(
|
|
current_user: CurrentUser = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""
|
|
현재 사용자 정보 조회
|
|
|
|
JWT 토큰을 기반으로 현재 로그인한 사용자 정보를 반환합니다.
|
|
"""
|
|
user = auth_service.get_user_by_id(db, current_user.id)
|
|
return user
|
|
|
|
@router.post("/refresh", response_model=Token)
|
|
async def refresh_token(
|
|
credentials: HTTPAuthorizationCredentials = Depends(security),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""
|
|
토큰 갱신
|
|
|
|
Refresh Token을 사용하여 새로운 Access Token을 발급합니다.
|
|
"""
|
|
token = credentials.credentials
|
|
payload = decode_token(token)
|
|
|
|
if not payload or payload.get("type") != "refresh":
|
|
raise AuthenticationError("유효하지 않은 Refresh Token입니다")
|
|
|
|
user_id = payload.get("sub")
|
|
user = auth_service.get_user_by_id(db, int(user_id))
|
|
|
|
if not user or not user.is_active:
|
|
raise AuthenticationError("사용자를 찾을 수 없습니다")
|
|
|
|
tokens = auth_service.create_tokens(user)
|
|
return tokens
|