客户登录后 GraphQL 仍返回访客价格、空购物车或错误客户组,属于高风险缓存串号。第一步不是清缓存,而是立即确认是否可能把一个客户的数据返回给另一个客户;若响应含个人数据,应先绕过相关 CDN 规则。
建立访客与登录请求对照
curl -sS -D /tmp/guest.h -H 'Content-Type: application/json' --data '{"query":"{ customerCart { id total_quantity } }"}' https://shop.example.com/graphql
curl -sS -D /tmp/customer.h -H 'Content-Type: application/json' -H 'Authorization: Bearer REDACTED' --data '{"query":"{ customerCart { id total_quantity } }"}' https://shop.example.com/graphql
Token 不要写入 shell history或工单。比较 Age、Cache-Control、Varnish/CDN 命中头和响应内容。登录请求出现公共缓存 HIT 就要优先修缓存策略。
确认 Authorization 到达 PHP
grep -R "fastcgi_param HTTP_AUTHORIZATION" /etc/nginx 2>/dev/null
grep -R "SetEnvIf Authorization" /etc/apache2 2>/dev/null
只能记录头是否存在,不能记录值。若源站看不到 Authorization,检查反向代理、WAF 和 FastCGI 参数。
审计缓存键与自定义 Resolver
grep -R --line-number "IdentityInterface|CacheableQueryInterface|getIdentities" app/code 2>/dev/null
grep -R --line-number "graphql" /etc/varnish /etc/nginx 2>/dev/null
公共商品查询可以缓存,但客户购物车、客户资料和个性化价格必须按身份正确隔离或禁止共享缓存。自定义 Resolver 若返回客户相关数据,不应只用 URL 和 query body 作为缓存键。
验收矩阵
准备访客、客户 A、客户 B 三个会话,以相同 query 连续交叉请求。购物车 ID、客户组价格和地址不得串用;注销后应恢复访客结果。测试还要覆盖 CDN HIT/MISS、Varnish 绕过和两台 Web 节点。
生产环境操作前的检查
针对“Magento 2 GraphQL 登录后仍返回访客缓存”进行处理时,先记录 Magento 版本、部署模式、问题 Store View、复现时间和最近一次发布。所有 SQL 默认先执行 SELECT;需要 UPDATE、DELETE、补偿命令或目录删除时,必须先确认命中范围并保留可恢复备份。多 Web 节点环境还要比较代码版本、app/etc/env.php 摘要和当前流量节点,避免只修复其中一台。
php bin/magento --version
php bin/magento deploy:mode:show
php bin/magento maintenance:status
php bin/magento indexer:status
php bin/magento cache:status
命令应由 Magento 文件所有者在项目根目录执行。生产站不要同时运行多个全量索引或静态部署任务;若涉及数据库结构、库存、支付或订单,先在脱敏的生产数据副本验证,再安排维护窗口。
建立可比较的排查记录
每次实验只改变一个变量,并保存“操作前值、执行命令、开始时间、结束时间、结果、回滚方式”。至少准备一个正常对象和一个异常对象作对照,例如两个 SKU、两张订单或访客与登录客户。若修复后仅当前对象恢复,而新建对象仍会复现,说明根因尚未消除。
| 检查点 | 需要记录 | 通过标准 |
|---|---|---|
| 数据层 | 主键、Store/Website、更新时间、关联行数 | 关系完整且无孤儿记录 |
| 应用层 | 异常堆栈、模块、Cron/消费者状态 | 无新异常并可重复执行 |
| 缓存与索引 | 索引模式、版本、源站和公网响应 | 按预期周期自动更新 |
| 业务回归 | 正常路径、失败路径、重复请求 | 结果一致且没有重复副作用 |
修复后的观察窗口
上线后不要只刷新一次页面就结束。至少观察一轮 Cron、队列消费和索引周期,并在两台节点、无痕浏览器及目标 Store View 重复验证。对日志、数据库行数、错误率和响应时间设置临时观察项;确认它们稳定后再移除调试日志。调试日志可能包含客户、订单或令牌信息,采集时要脱敏,问题结束后及时关闭。

