# sanguo_api/auth.py """JWT 单用户认证。secret/用户名/密码 hash 来自 config/backtest.yaml。""" import os from datetime import datetime, timedelta, timezone import jwt from passlib.context import CryptContext from fastapi import HTTPException, status _CONFIG = {"secret": "change-me", "expire_minutes": 60, "algorithm": "HS256"} _pwd = CryptContext(schemes=["bcrypt"], deprecated="auto") def set_jwt_config(secret: str, expire_minutes: int, algorithm: str = "HS256"): _CONFIG.update(secret=secret, expire_minutes=expire_minutes, algorithm=algorithm) def hash_password(password: str) -> str: return _pwd.hash(password) def verify_password(password: str, password_hash: str) -> bool: return _pwd.verify(password, password_hash) def create_token(username: str) -> str: payload = { "sub": username, "exp": datetime.now(timezone.utc) + timedelta(minutes=_CONFIG["expire_minutes"]), } return jwt.encode(payload, _CONFIG["secret"], algorithm=_CONFIG["algorithm"]) def verify_token(token: str) -> str: try: payload = jwt.decode(token, _CONFIG["secret"], algorithms=[_CONFIG["algorithm"]]) return payload["sub"] except jwt.PyJWTError: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="无效 token")