auth.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. from fastapi import HTTPException, Query, Depends
  2. from fastapi.security import OAuth2PasswordBearer
  3. from typing import Optional, Annotated
  4. from pydantic import BaseModel
  5. import jwt
  6. from ..db.redis_client import get_app_user
  7. from ..config.config import Config
  8. config = Config()
  9. oauth2_scheme_optional = OAuth2PasswordBearer(tokenUrl="/users/token", auto_error=False)
  10. class UserContext(BaseModel):
  11. user_id: str
  12. app_name: str
  13. async def resolve_user_id(
  14. jwt_token: Annotated[Optional[str], Depends(oauth2_scheme_optional)] = None,
  15. source: Optional[str] = Query(default=None),
  16. token: Optional[str] = Query(default=None),
  17. ) -> UserContext:
  18. if source == "app" and token:
  19. app_user = get_app_user(token)
  20. if not app_user:
  21. raise HTTPException(status_code=401, detail="无效的 App token")
  22. user_id = app_user.get("userId")
  23. app_name = app_user.get("appName")
  24. if not user_id or not app_name:
  25. raise HTTPException(status_code=401, detail="无效的 App token")
  26. return UserContext(
  27. user_id=user_id,
  28. app_name=app_name,
  29. )
  30. if not jwt_token:
  31. raise HTTPException(status_code=401, detail="未提供认证令牌")
  32. try:
  33. payload = jwt.decode(jwt_token, config.SECRET_KEY, algorithms=[config.ALGORITHM])
  34. user_id = payload.get("userId")
  35. if not user_id:
  36. raise HTTPException(status_code=401, detail="无效的令牌")
  37. return UserContext(
  38. user_id=user_id,
  39. app_name="com.yunxingshnegtai",
  40. )
  41. except jwt.PyJWTError:
  42. raise HTTPException(status_code=401, detail="无效的令牌")