订单详情接口是 GET /api/orders/88123?tenantId=1002,把 1002 改成 1003,返回的是另一家公司的订单,响应里带收件人手机号。抓包看请求头里的 token 属于 1002,接口没有任何报错。乍看像缓存或者权限的锅,追下去往往不是。

curl -s -H "Authorization: Bearer $T1"
  'https://api.example.com/api/orders/88123?tenantId=1003'
# 期望 403 实际 200 且返回体 tenant_id 为 1003

追下去是这么回事:控制器把 tenantId 当成普通查询参数直接拼进 where 条件,token 里的租户信息只用来认人,没有参与数据过滤。参数一换 SQL 就跟着换,鉴权那一层根本没看这个字段。

「租户上下文信任前端」这个问题文档写得含糊,实际行为以当前版本为准,别照旧版本的结论套。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。

偶发问题先统计频率,一小时几次和一天一次,查法完全不同。

具体做法是,把租户 id 从登录态取 请求参数只当校验用 不一致返回 403;在数据访问层统一注入租户条件 不让业务代码自己拼;补一条两个租户交叉访问的用例 每次发版跑一遍。

验收就看一点,用两个租户的 token 交叉请求同一个订单号,两边都返回 403,同一 token 请求自家订单仍是 200。

作者 9823189