Files
problem-bank/backend/auth.py
2026-03-05 11:50:15 +08:00

55 lines
2.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from datetime import datetime, timedelta, timezone
import importlib.util
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
_jose_spec = importlib.util.find_spec("jose")
_jose_origin = _jose_spec.origin if _jose_spec else None
_incompatible_jose = bool(_jose_origin and _jose_origin.endswith("site-packages/jose.py"))
try:
import jwt
from jwt import InvalidTokenError as JWTError
except Exception as exc:
if not _incompatible_jose:
try:
from jose import JWTError, jwt
except Exception as fallback_exc:
raise RuntimeError(
"JWT 依赖不可用,请安装 python-jose[cryptography] 或 PyJWT"
) from fallback_exc
else:
raise RuntimeError(
"检测到不兼容依赖 jose请卸载 jose 后安装 python-jose[cryptography] 或安装 PyJWT"
) from exc
from backend.config import settings
security = HTTPBearer()
def create_access_token(subject: str) -> str:
expire = datetime.now(timezone.utc) + timedelta(minutes=settings.access_token_expire_minutes)
payload = {"sub": subject, "exp": expire}
return jwt.encode(payload, settings.jwt_secret_key, algorithm=settings.jwt_algorithm)
def verify_password(username: str, password: str) -> bool:
return username == settings.admin_username and password == settings.admin_password
def get_current_user(
credentials: HTTPAuthorizationCredentials = Depends(security),
) -> str:
token = credentials.credentials
try:
payload = jwt.decode(token, settings.jwt_secret_key, algorithms=[settings.jwt_algorithm])
username: str | None = payload.get("sub")
if not username:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="无效Token")
return username
except JWTError as exc:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="登录已过期") from exc