"""API Key 认证依赖 用于保护写操作(POST/PUT/DELETE)。 - 若 settings.API_KEY 为空,则放行所有请求(纯内网场景)。 - 若已配置,则要求请求头携带正确的 X-API-Key,否则返回 401。 """ import hmac from typing import Optional from fastapi import Header, HTTPException, status from app.core.config import settings def _key_matches(provided: Optional[str], expected: str) -> bool: """常量时间比较密钥,避免时序旁路泄露密钥长度/前缀信息""" if not provided: return False return hmac.compare_digest(provided.encode(), expected.encode()) async def require_api_key( x_api_key: Optional[str] = Header(default=None, alias="X-API-Key"), ) -> None: """校验 API Key(可选启用)""" if not settings.API_KEY: return if not _key_matches(x_api_key, settings.API_KEY): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="API Key 无效或缺失", ) async def require_agent_key( x_agent_key: Optional[str] = Header(default=None, alias="X-Agent-Key"), ) -> None: """校验 Agent 上报 Key(可选启用)""" if not settings.AGENT_KEY: return if not _key_matches(x_agent_key, settings.AGENT_KEY): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Agent Key 无效或缺失", )