eff9ed2ae9
- bridge.py: lifespan连miniQMT, health/order/account/positions, 连不上不崩 - xt_gateway.py: xtquant单例封装(延迟import), 照搬check_xtquant验证模式 - auth.py: X-Bridge-Token校验(hmac防时序攻击), 未配token返回503不裸奔 - requirements.txt(fastapi+uvicorn) + README.md(Windows部署步骤) 安全: 无硬编码secret, token/userdata/account均走环境变量(grep验证CLEAN)
45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
"""Token 鉴权:每个请求带 X-Bridge-Token header,bridge 校验。
|
||
|
||
设计(spec §6):
|
||
- bridge 从环境变量 BRIDGE_TOKEN 读期望值,不进 git。
|
||
- 不符/缺失 -> 401。
|
||
- /health 豁免(该路由不挂 Depends(verify_token))。
|
||
- 使用 hmac.compare_digest 防时序攻击。
|
||
"""
|
||
import hmac
|
||
import logging
|
||
import os
|
||
|
||
from fastapi import HTTPException, Request
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
def get_expected_token() -> str | None:
|
||
"""从环境变量读 BRIDGE_TOKEN。"""
|
||
return os.environ.get("BRIDGE_TOKEN")
|
||
|
||
|
||
def verify_token(request: Request) -> None:
|
||
"""FastAPI Depends:校验 X-Bridge-Token header。
|
||
|
||
Raises:
|
||
HTTPException 503: BRIDGE_TOKEN 未配置(安全默认:拒绝所有受保护请求)。
|
||
HTTPException 401: token 缺失或不匹配。
|
||
"""
|
||
expected = get_expected_token()
|
||
if not expected:
|
||
# 未配置 token -> 拒绝所有受保护请求(不裸奔)
|
||
raise HTTPException(
|
||
status_code=503,
|
||
detail="BRIDGE_TOKEN 环境变量未配置,拒绝服务",
|
||
)
|
||
|
||
token = request.headers.get("X-Bridge-Token", "")
|
||
if not hmac.compare_digest(token, expected):
|
||
logger.warning(
|
||
"token 校验失败 source=%s",
|
||
request.client.host if request.client else "unknown",
|
||
)
|
||
raise HTTPException(status_code=401, detail="token 无效")
|