前端请求里明明写了 Authorization: Bearer ...,Magento GraphQL 返回的 customer 却是未登录,价格也按游客组计算。先不要怀疑 Token 内容,最常见的情况是它根本没有到达 PHP。

用同一个Token绕过每一层测试

从浏览器复制请求为 curl,分别请求公网域名、CDN 后的源站地址和本机 upstream。响应在哪一层开始变化,就查那一层的头转发。日志只记录 Authorization 是否存在和长度,不要打印完整 Token。

curl -i https://shop.example.com/graphql   -H 'Content-Type: application/json'   -H 'Authorization: Bearer REDACTED'   --data '{"query":"{customer{firstname}}"}'

Nginx、Apache、负载均衡和 WAF 都可能过滤 Authorization。PHP-FPM 环境还要确认该头以预期变量传入。修配置后在应用入口做一次临时的“是否收到”日志,比重复生成 Token 更快。

如果公网请求丢头而直连 PHP 正常,要沿代理链一段一段加回。Nginx 常见的是 FastCGI 参数没有传递 HTTP_AUTHORIZATION;Apache 可能被 rewrite 或安全模块处理;CDN 则可能没有把该头加入允许转发列表。修改任何一层后都用同一条 curl 复测,避免同时改三处后无法判断真正原因。

确认Token属于客户,而不是集成或后台用户

Magento 的 customer、admin 和 integration token 用途不同。用生成客户 Token 的 mutation 重新生成一枚,在没有 CDN 缓存的环境直接查询 customer。还要带正确 Store 头,多网站共享邮箱时,Token 的网站上下文不一致会产生权限或数据差异。

缓存不能只按GraphQL正文区分

如果游客先请求相同 query,CDN 随后把缓存响应发给登录客户,看起来就像 Token 被忽略。检查 GraphQL POST/GET 的缓存规则、Vary 信息以及 Magento 返回的缓存标识。包含 customer 私有数据的请求不应该命中公共游客缓存。

我会在响应头里记录 cache HIT/MISS,并用两个不同客户的 Token 交叉测试:A 不能看到 B 的数据,登录请求也不能复用游客响应。这比只验证“终于返回 firstname 了”更重要。

对于只查询公开商品的请求,也别简单地把 Authorization 从缓存键删掉。登录客户可能有专属客户组价格、共享目录或可见性。可以先对照 Magento 返回的缓存上下文标识,再配置 Varnish/CDN;自己拼一个只按 query hash 的键,最容易造成跨客户数据污染。

修好后再测试 Token 过期、空 Authorization、错误 Store 头和并发请求。最终结论应明确是代理丢头、Token 类型、网站上下文还是缓存键,而不是把所有 GraphQL 401 都归到“重新登录”。