前端查订单的 query 只传 orderId,登录 A 账号把 id 从 8812 换成 8813,返回里是 B 账号的收货地址和手机号。响应里没有报错,字段全都正常返回。碰到这种情况,我一般先确认改动有没有真的生效。
原因不复杂,权限校验放在了列表接口,单条查询的 resolver 里只按主键取数据。GraphQL 由前端自由挑字段,越权拿到的数据比 REST 更多。网关层只认登录态,不认这条数据归谁。
「GraphQL 越权查询」这类改动最怕改一半,回滚脚本先准备好,再动生产。别只看报错的最后一行,往上看几行,真正的起因通常在上面。
order = db.query(Order).filter_by(id=oid, user_id=ctx.user_id).first()
if not order:
raise GraphQLError('not found')
同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。
具体做法是,resolver 里取数据时带上当前用户的 id 作为条件;封装一个统一的数据加载层 禁止业务直接按主键查;对敏感字段单独加一层归属判断;越权返回 404 不要返回 403 免得暴露数据是否存在。
最后用这个标准收尾,换成别人的 orderId 返回 not found 自己的单照常返回 字段一个不少。
