deps.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. """
  2. FastAPI 依赖项:JWT令牌解析、当前用户加载、按角色鉴权。
  3. """
  4. from __future__ import annotations
  5. from typing import Annotated
  6. from uuid import UUID
  7. from fastapi import Depends, HTTPException, status
  8. from fastapi.security import OAuth2PasswordBearer
  9. from jose import JWTError
  10. from sqlmodel import Session, select
  11. from app.core.security import decode_token
  12. from app.db import get_session
  13. from app.models import User, UserRole
  14. #定义从请求头获取Token的规则
  15. oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token") #登录接口地址
  16. #定义数据库会话和Token的依赖
  17. SessionDep = Annotated[Session, Depends(get_session)]
  18. TokenDep = Annotated[str, Depends(oauth2_scheme)]
  19. def get_current_user(session: SessionDep, token: TokenDep) -> User:
  20. #获取当前登录用户
  21. try:
  22. payload = decode_token(token) # 解码令牌,得到用户信息
  23. sub = payload.get("sub") # 获取用户ID
  24. if not sub:
  25. raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token subject")
  26. user_id = UUID(sub)
  27. except (JWTError, ValueError):
  28. raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
  29. user = session.exec(select(User).where(User.id == user_id)).first()
  30. if not user:
  31. raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found")
  32. return user
  33. def require_role(*roles: UserRole):
  34. #接口角色权限控制
  35. def _guard(current_user: Annotated[User, Depends(get_current_user)]) -> User:
  36. if current_user.role not in roles:
  37. raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Insufficient permissions")
  38. return current_user
  39. return _guard