v0.1.0: CRM/ERP 系统内测版本 - 安全加固完成
- Docker bridge 网络隔离(8000 端口封死) - Gunicorn 4 Worker 多进程 - Alembic 数据库迁移基线 - 日志轮转 20m×3 - JWT 密钥 + DB 密码 + CORS 收紧 - 3-2-1 备份链路(NAS + R740-B 冷备) - 连接池 pool_pre_ping + pool_recycle=3600
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
全局审计中间件
|
||||
拦截所有入站 HTTP 请求,记录:方法、URL、客户端 IP、耗时、响应状态码。
|
||||
日志输出到标准 logging,生产环境可对接 ELK / Loki 等日志收集系统。
|
||||
"""
|
||||
|
||||
import logging
|
||||
import time
|
||||
|
||||
from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
|
||||
from starlette.requests import Request
|
||||
from starlette.responses import Response
|
||||
|
||||
# 配置审计专用 logger,与业务日志分离
|
||||
audit_logger = logging.getLogger("audit")
|
||||
audit_logger.setLevel(logging.INFO)
|
||||
|
||||
|
||||
class AuditMiddleware(BaseHTTPMiddleware):
|
||||
"""
|
||||
审计中间件 - 记录每个请求的关键信息。
|
||||
日志格式: [AUDIT] <客户端IP> <方法> <URL> <状态码> <耗时ms>
|
||||
"""
|
||||
|
||||
async def dispatch(
|
||||
self, request: Request, call_next: RequestResponseEndpoint
|
||||
) -> Response:
|
||||
# 提取客户端真实 IP (优先取反向代理传递的 X-Forwarded-For)
|
||||
client_ip = request.headers.get(
|
||||
"X-Forwarded-For", request.client.host if request.client else "unknown"
|
||||
)
|
||||
method = request.method
|
||||
url = str(request.url)
|
||||
|
||||
start_time = time.perf_counter()
|
||||
|
||||
try:
|
||||
response = await call_next(request)
|
||||
except Exception:
|
||||
# 未捕获异常也要记录审计日志
|
||||
elapsed_ms = (time.perf_counter() - start_time) * 1000
|
||||
audit_logger.error(
|
||||
"[AUDIT] %s %s %s 500 %.1fms (unhandled exception)",
|
||||
client_ip, method, url, elapsed_ms,
|
||||
)
|
||||
raise
|
||||
|
||||
elapsed_ms = (time.perf_counter() - start_time) * 1000
|
||||
|
||||
audit_logger.info(
|
||||
"[AUDIT] %s %s %s %d %.1fms",
|
||||
client_ip, method, url, response.status_code, elapsed_ms,
|
||||
)
|
||||
|
||||
# 将审计信息注入响应头 (方便调试,生产环境可移除)
|
||||
response.headers["X-Request-Duration-Ms"] = f"{elapsed_ms:.1f}"
|
||||
|
||||
return response
|
||||
Reference in New Issue
Block a user