import uuid from fastapi import APIRouter, Depends, HTTPException, status from jose import JWTError, jwt from sqlalchemy.orm import Session from app.core.config import settings from app.core.database import get_db from app.core.deps import get_current_user from app.core.security import ( create_access_token, create_refresh_token, get_password_hash, verify_password, ) from app.models.user import User from app.schemas import RefreshRequest, TokenResponse, UserLogin, UserOut, UserRegister router = APIRouter(prefix="/auth", tags=["auth"]) @router.post("/register", response_model=UserOut, status_code=status.HTTP_201_CREATED) def register(data: UserRegister, db: Session = Depends(get_db)): if db.query(User).filter(User.username == data.username).first(): raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户名已存在") user = User(username=data.username, password_hash=get_password_hash(data.password)) db.add(user) db.commit() db.refresh(user) return user @router.post("/login", response_model=TokenResponse) def login(data: UserLogin, db: Session = Depends(get_db)): user = db.query(User).filter(User.username == data.username).first() if user is None or not verify_password(data.password, user.password_hash): raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="用户名或密码错误") return TokenResponse( access_token=create_access_token(str(user.id)), refresh_token=create_refresh_token(str(user.id)), ) @router.post("/refresh", response_model=TokenResponse) def refresh(data: RefreshRequest, db: Session = Depends(get_db)): try: payload = jwt.decode(data.refresh_token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM]) user_id = payload.get("sub") token_type = payload.get("type") if user_id is None or token_type != "refresh": raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="无效刷新令牌") except JWTError as exc: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="无效刷新令牌") from exc user = db.get(User, uuid.UUID(user_id)) if user is None: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="用户不存在") return TokenResponse( access_token=create_access_token(str(user.id)), refresh_token=create_refresh_token(str(user.id)), ) @router.get("/me", response_model=UserOut) def me(current_user: User = Depends(get_current_user)): return current_user