feat: API 安全加固 — 请求体大小限制、审计日志、健康检查免限速
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
"""FastAPI 服务层."""
|
"""FastAPI 服务层."""
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -84,8 +85,36 @@ async def security_headers_middleware(request: Request, call_next):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@app.middleware("http")
|
||||||
|
async def body_size_limit_middleware(request: Request, call_next):
|
||||||
|
"""限制请求体大小(防止内存耗尽攻击)."""
|
||||||
|
content_length = request.headers.get("content-length")
|
||||||
|
max_size = int(os.environ.get("MAX_REQUEST_BODY_SIZE", str(10 * 1024 * 1024))) # 默认 10MB
|
||||||
|
if content_length and int(content_length) > max_size:
|
||||||
|
raise HTTPException(status_code=413, detail="请求体过大")
|
||||||
|
return await call_next(request)
|
||||||
|
|
||||||
|
|
||||||
|
@app.middleware("http")
|
||||||
|
async def audit_log_middleware(request: Request, call_next):
|
||||||
|
"""记录所有 API 请求的审计日志."""
|
||||||
|
start = time.time()
|
||||||
|
response = await call_next(request)
|
||||||
|
duration_ms = (time.time() - start) * 1000
|
||||||
|
logger.info(
|
||||||
|
"audit: %s %s → %d (%.1fms) [%s]",
|
||||||
|
request.method, request.url.path,
|
||||||
|
response.status_code, duration_ms,
|
||||||
|
request.client.host if request.client else "unknown",
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
@app.middleware("http")
|
@app.middleware("http")
|
||||||
async def rate_limit_middleware(request: Request, call_next):
|
async def rate_limit_middleware(request: Request, call_next):
|
||||||
|
# 健康检查和根路径不需要速率限制
|
||||||
|
if request.url.path in ("/api/v1/health", "/"):
|
||||||
|
return await call_next(request)
|
||||||
await rate_limiter(request)
|
await rate_limiter(request)
|
||||||
response = await call_next(request)
|
response = await call_next(request)
|
||||||
return response
|
return response
|
||||||
|
|||||||
Reference in New Issue
Block a user