现象:不带任何 Token 请求 /api/v1/products/scan/{sn} 等接口直接 200,
业务数据(产品、任务、订单)可被匿名读取。
同时这也是审计「操作人恒为未认证」的根因:
这些路由只挂了 Depends(get_db),JWT 依赖不执行 →
request.state.audit_user 从未写入 → 中间件只能记成「未认证」。
修复:为 3 个文件共 9 条 GET 路由统一补上 Depends(get_current_user)
products.py GET /qrcode/{serial_number}
GET /scan/{serial_number} ← 匿名可读产品数据
GET / ← 列表
GET /{product_id}
GET /{product_id}/messages
tasks.py GET /
GET /{task_id}
GET /by-product/{product_id}
orders.py GET /
未改动:notifications.py 本就有鉴权;records.py 无 GET 路由。
三个文件原本已 import get_current_user,未新增导入。
落地前已排查「是否有意免登」:
- /products/qrcode/{sn} 是 PC 打印标签用,非免登场景
- 外部系统调用走独立通道 /external/products/lookup(X-API-Key 鉴权),
与内部 /products/* 完全分离
故内部读接口本就应要求登录。
⚠️ 连带影响:二维码标签编码的是前端页面地址(/sn/{序列号}),
此前任何人用手机相机扫码即可查看产品状态,现在会要求登录。
若业务需要免登查询,应走带 API-Key 的 /external/products/lookup,
而不是让内部接口裸奔。
42 lines
1.3 KiB
Python
42 lines
1.3 KiB
Python
"""生产订单 API 端点"""
|
|
from __future__ import annotations
|
|
import uuid
|
|
from fastapi import APIRouter, Depends, Query
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy.orm import selectinload
|
|
|
|
from app.core.database import get_db
|
|
from app.models.production_order import ProductionOrder
|
|
from app.schemas.order import OrderCreate, OrderResponse
|
|
from app.services.auth_service import get_current_user
|
|
|
|
router = APIRouter(prefix="/orders", tags=["订单管理"])
|
|
|
|
|
|
@router.get("/", response_model=list[OrderResponse])
|
|
async def list_orders(
|
|
skip: int = Query(0, ge=0),
|
|
limit: int = Query(50, ge=1, le=200),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: dict = Depends(get_current_user),
|
|
):
|
|
result = await db.execute(
|
|
select(ProductionOrder).offset(skip).limit(limit).order_by(ProductionOrder.created_at.desc())
|
|
)
|
|
orders = result.scalars().all()
|
|
return [OrderResponse.model_validate(o) for o in orders]
|
|
|
|
|
|
@router.post("/", response_model=OrderResponse, status_code=201)
|
|
async def create_order(
|
|
data: OrderCreate,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: dict = Depends(get_current_user),
|
|
):
|
|
order = ProductionOrder(**data.model_dump())
|
|
db.add(order)
|
|
await db.commit()
|
|
await db.refresh(order)
|
|
return OrderResponse.model_validate(order)
|