跳到主要内容

ArtinTech Solution

Fixing an Intermittent 403 Error Caused by Cache TTL

间歇性 bug 是最难诊断的,因为它连调试最基本的一步都过不了:按需复现。一家店铺侧边购物车中的“删除商品”按钮,对部分访客、在部分时间会返回 403 Forbidden 错误,而 PHP 错误日志里没有任何有用的线索。

读懂失败的特征

AJAX 请求的响应内容只有一个 -1,状态码为 HTTP 403。这个组合正是 WordPress 中 check_ajax_referer() 调用失败的特征,也就是每个规范的 AJAX 处理程序在做任何事之前都会执行的安全 nonce 校验。页面发送的 nonce 与服务器预期的根本不一致。

为什么一个本来有效的 nonce 会失效

WordPress 的 nonce 不是永久的:它们在每次页面加载时生成,大约 24 到 48 小时后过期,依赖的是一个滚动的时间窗口,而不是固定值。然而,该网站的 LiteSpeed 整页缓存被配置为 7 天的 TTL,也就是说,一个缓存页面在生成后最多一整周内,都可能原封不动地提供给每一位访客。

任何在缓存约两天后仍从缓存中提供的页面,发出去的 nonce 在真实访客尝试使用时早已过期;问题不在该访客的会话,而在于 HTML 本身相对于 WordPress 的安全时钟已经过时。

修复方法,以及为什么这是真正的修复而不是权宜之计

把页面缓存 TTL 降到 6 小时(明显低于 WordPress nonce 的最短有效期),问题立刻彻底解决,因为它针对的是真正的时间错配,而不是掩盖症状。排查过程中,我们还从结账页移除了一个与此无关、重复的购物车界面,因为结账页自带的订单汇总已经显示了同样的信息。

要点总结

  • 响应内容为 -1 且状态码为 HTTP 403,几乎就是 WordPress nonce 校验失败的指纹;值得一眼就认出来。
  • 整页缓存 TTL 与 WordPress 安全令牌的有效期是两项必须相互匹配的设置,而默认情况下没有任何机制来保证这一点。
  • 看似随机的间歇性 bug,往往是两个各自正常工作的系统之间的时间错配。

相关阅读:六小时的时间戳偏差、网站维护到底包括什么。

在您自己的 WooCommerce 或 WordPress 后台遇到类似限制?和我们聊聊:ArtinTech Solution 正是打造这类定制店铺工具的团队。

Share this article

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注