from typing import Annotated import redis.asyncio as redis from fastapi import Depends, Header, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from app.core.security import decode_access_token from app.database import get_db from app.models.user import User from app.redis_client import redis_dependency from app.services import auth as auth_service DbSession = Annotated[AsyncSession, Depends(get_db)] RedisClient = Annotated[redis.Redis, Depends(redis_dependency)] async def get_current_user( db: DbSession, redis: RedisClient, authorization: Annotated[str | None, Header()] = None, ) -> User: if not authorization or not authorization.lower().startswith("bearer "): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="未提供有效的认证令牌", ) token = authorization[7:].strip() if not token: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="未提供有效的认证令牌", ) user_id = await auth_service.session_user_id(redis, token) if user_id is None: payload = decode_access_token(token) if payload is None or payload.get("sub") is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="令牌无效或已过期", ) user_id = int(payload["sub"]) user = await auth_service.get_user_by_id(db, user_id) if user is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="用户不存在", ) return user CurrentUser = Annotated[User, Depends(get_current_user)]