from fastapi import Request import db from app.core.security import token_digest # 管理后台写操作统一审计;不保存令牌明文和请求正文。 async def admin_audit_middleware(request: Request, call_next): should_audit = ( request.url.path.startswith("/admin/") and request.method not in ("GET", "HEAD", "OPTIONS") and not request.url.path.startswith("/admin/audit-log/") ) status_code = 500 try: response = await call_next(request) status_code = response.status_code return response finally: if should_audit: try: principal = getattr(request.state, "admin_principal", None) token = request.headers.get("authorization", "") conn = db.get_conn() conn.execute( """INSERT INTO admin_audit_logs (actor_hash,actor_username,actor_roles,auth_type,action,method,path,target,result,status_code,ip,user_agent) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)""", ( principal.actor_hash if principal else (token_digest(token)[:16] if token else "anonymous"), principal.username if principal else "anonymous", ",".join(principal.roles) if principal else "", principal.auth_type if principal else "", request.url.path.removeprefix("/admin/"), request.method, request.url.path, request.url.query[:500], "success" if 200 <= status_code < 400 else "fail", status_code, request.client.host if request.client else "", request.headers.get("user-agent", "")[:300], ), ) conn.commit() conn.close() except Exception as audit_error: print("管理员审计日志写入失败:", audit_error)