diff --git a/backend/app/api/v1/endpoints/products.py b/backend/app/api/v1/endpoints/products.py index 878faa8..016985d 100644 --- a/backend/app/api/v1/endpoints/products.py +++ b/backend/app/api/v1/endpoints/products.py @@ -26,12 +26,21 @@ router = APIRouter(prefix="/products", tags=["产品管理"]) # ============================================================ @router.get("/qrcode/{serial_number}") -async def get_product_qrcode( - serial_number: str, - current_user: dict = Depends(get_current_user), -): +async def get_product_qrcode(serial_number: str): """ 生成产品二维码(PNG 图片)。 + + ⚠️ 本接口【刻意不加鉴权】: + 前端以 `` 引用它,而 + 无法携带 Authorization 头 —— 加了鉴权会让所有二维码图片加载失败, + 并在审计里刷出大量 401。 + + 不加鉴权是安全的:本函数**不查数据库**,只校验长度并把这个字符串渲染成 + 二维码,没有任何业务数据泄露面(序列号本身就是调用方提供的)。 + + 也刻意不支持 ?token= 兜底:把 JWT 放进 URL 会渗进访问日志、浏览器历史 + 与 Referer,比它想解决的问题更糟。 + 内容为 16 位序列号,扫描后可调用 /scan/{serial_number} 查询产品。 尺寸:300×300 px,用于 PC 端打印或嵌入标签。 """ diff --git a/backend/app/core/audit_middleware.py b/backend/app/core/audit_middleware.py index f42f1b0..ffddc89 100644 --- a/backend/app/core/audit_middleware.py +++ b/backend/app/core/audit_middleware.py @@ -56,7 +56,16 @@ _TRACKED_READ_PREFIXES = ( ) # 永久忽略的路径前缀 -_IGNORED_PREFIXES = ("/health", "/docs", "/redoc", "/openapi.json") +# +# 两类内容: +# 1. 探针与文档(/health、/docs…)—— 噪声没有审计价值 +# 2. 图片类端点(/api/v1/products/qrcode)—— 走 加载, +# 一次列表页渲染就会并发拉几十张图,逐条留痕会把审计日志塞满, +# 真正有价值的操作反而被淹没。它也不含业务数据(只渲染二维码图片)。 +_IGNORED_PREFIXES = ( + "/health", "/docs", "/redoc", "/openapi.json", + "/api/v1/products/qrcode", +) # 路径段 → 审计模块 _PATH_MODULE: dict[str, str] = {