PMFlow/backend/app/api/auth.py

49 lines
1.5 KiB
Python

"""认证 API"""
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select
from ..database import get_db
from ..models import User, UserStatus
from ..schemas import UserLoginResponse
from ..services.auth import AuthService
router = APIRouter(prefix="/auth", tags=["auth"])
@router.post("/login", response_model=UserLoginResponse)
async def login(
credentials: OAuth2PasswordRequestForm = Depends(),
db: AsyncSession = Depends(get_db),
):
"""用户登录,返回 JWT"""
result = await db.execute(
select(User).where(User.username == credentials.username)
)
user = result.scalar_one_or_none()
if not user or not AuthService.verify_password(
credentials.password, user.password_hash
):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Bearer"},
)
if not getattr(user, "is_active", True) or user.status != UserStatus.ACTIVE.value:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="User is disabled",
)
access_token = AuthService.create_access_token(data={"sub": user.username})
return UserLoginResponse(
access_token=access_token,
token_type="bearer",
user=user.to_dict(),
)