保存产品偶尔提示 Invalid Form Key,重新登录又能工作;保存系统配置却几乎必现。团队把 max_input_vars 从 1000 调到 10000,问题仍然存在。原因是 Form Key 错误只是校验结果,不是单一根因。
先比较失败请求中的两个 Form Key
一个来自当前 session,另一个随表单提交。用浏览器 Network 查看请求中是否真的包含 form_key、字段是否被截断、提交前页面是否已停留很久。服务端日志只记录哈希或是否一致,不要打印完整 session 内容。
如果小表单也随机失败,优先查会话;只有字段很多的产品/配置页失败,才重点看 max_input_vars、post_max_size、Web 服务器请求限制和 WAF。
会话为什么会在后台请求之间变化
检查 Admin Cookie 的 Domain、Path、Secure、SameSite 与 Lifetime。后台通过 HTTPS,代理回源却让 Magento 认为是 HTTP,会生成不一致 Cookie。多节点如果 session 存本地文件,请求切换节点后也会拿不到原 session。
Redis session 场景查看连接错误、淘汰、TTL 与锁超时。后台保存大产品耗时很长,session 锁或连接超时可能在请求完成前就让下一请求使用新会话。
字段截断要用最小复现证明
逐步增加可配置商品选项或系统配置字段,观察 form_key 是否位于被截断部分。PHP 的 max_input_vars 按嵌套输入展开计数,页面看起来只有几百行,实际字段可能数千。修改参数后要确认 CLI 与 PHP-FPM 使用的不是两份 php.ini,并平滑重载正确的 FPM 池。
php --ini
php -i | grep -E 'max_input_vars|post_max_size'
systemctl reload php-fpm命令行配置只能辅助,最终应通过 Web 请求暴露的受控诊断确认 FPM 值,诊断页面用完立即移除。
代理不应缓存后台页面
若 CDN/Varnish 错误缓存 Admin HTML,页面里的 form_key 属于旧会话,提交必然失败。后台路径应正确 bypass 公共缓存,响应也不应被共享。修复后跨节点连续保存、小表单与大表单都通过,长时间停留后的过期行为有明确提示,才能结束排查。

