from datetime import datetime, timedelta from typing import Any, Optional from jose import jwt, JWTError from fastapi import Depends, HTTPException, status, Request from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from sqlalchemy.orm import Session from app.config import get_settings from app.database import get_db settings = get_settings() security = HTTPBearer(auto_error=False) def create_access_token( data: dict, expires_delta: Optional[timedelta] = None, ) -> str: to_encode = data.copy() expire = datetime.utcnow() + (expires_delta or timedelta(minutes=settings.JWT_ACCESS_TOKEN_EXPIRE_MINUTES)) to_encode.update({"exp": expire}) return jwt.encode(to_encode, settings.JWT_SECRET_KEY, algorithm=settings.JWT_ALGORITHM) def decode_access_token(token: str) -> dict: try: payload = jwt.decode(token, settings.JWT_SECRET_KEY, algorithms=[settings.JWT_ALGORITHM]) return payload except JWTError: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="无效的认证凭证", ) async def get_current_user(request: Request) -> dict: credentials: Optional[HTTPAuthorizationCredentials] = await security(request) if not credentials: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="未提供认证凭证", ) token = credentials.credentials payload = decode_access_token(token) return payload async def get_optional_user(request: Request) -> Optional[dict]: try: return await get_current_user(request) except HTTPException: return None