当动态页面(如登录表单、结账流程和已认证应用路由)被过于激进地缓存时,可能会出现问题。
常见症状包括:
- 用户可以加载登录页面,但提交后登录表单失败。
- 成功登录后会话无法持久。
- 源站发送
Set-Cookie标头,但浏览器从未存储 cookie。 - 出现挑战页面,但解决后用户返回登录页面或丢失表单状态。
一个常见原因是配置了 Cache Rule 或旧版 Page Rule 来缓存动态 HTML。
这通常发生在以下所有条件为真时:
- 页面配置为 Eligible for cache(符合缓存条件) 或 Cache Everything(全部缓存)。
- 响应是动态 HTML,如
/login或/account。 - 源站发送
Set-Cookie标头。 - Edge TTL 或状态码 TTL 覆盖源站缓存指令。
在此配置中,Cloudflare 可以缓存响应并在响应存储到边缘之前移除 Set-Cookie 标头。因此,浏览器收到登录页面但从未获得下一次请求所需的会话 cookie。
检查登录页面或其他动态路由的响应。
如果您同时看到以下两者,页面可能在不应缓存时被缓存:
CF-Cache-Status: HIT或CF-Cache-Status: EXPIRED- 响应中没有
Set-Cookie标头,即使源站通常设置一个
您还可能在表单提交后看到特定于框架的失败,例如:
- 重定向回登录页面
- 登录后出现
403或500 - CSRF 验证错误
- 缺少服务器端会话状态
此问题在使用首次页面加载依赖会话或 CSRF cookie 的框架中很常见,包括 JavaServer Faces、ASP.NET、PHP 会话处理程序、Django、Rails 和 Laravel。
不要缓存登录页面或其他已认证的 HTML。
相反:
- 将 Eligible for cache(符合缓存条件) 或 Cache Everything(全部缓存) 限制为仅静态路径。
- 添加更具体的 Cache Rule,对
/login、/account、/cart、/checkout和应用 API 路径等路由绕过或禁用缓存。 - 如果源站必须控制缓存,移除任何强制页面被缓存的 Edge TTL 覆盖。
- 验证修复后的响应现在返回
CF-Cache-Status: DYNAMIC、MISS或BYPASS,并保留Set-Cookie。
有关 cookie 行为的更多信息,请参阅 Set-Cookie 响应标头与 Cache 的交互。
安全挑战也可能中断动态流程。
两种常见模式是:
- 登录页面的初始
GET请求触发挑战。用户解决挑战,但应用程序丢失原始会话或 CSRF 上下文。 - 提交登录表单或其他敏感操作的
POST请求触发挑战。浏览器可能必须在挑战后重复请求,这可能破坏原始表单提交。
检查 WAF 自定义规则、托管规则 或速率限制规则 是否应用于登录路径。
如果问题仅影响 /login、/signin、/checkout 或 /api/auth/* 等路由,且在为这些路径禁用挑战时应用程序正常工作,挑战可能正在中断流程。
使用以下方法之一:
- 从挑战规则中排除登录或表单提交路径。
- 缩小规则表达式,使其仅应用于可疑流量。
- 如果必须保护该路由,在页面加载时使用干扰较小的控制,并在流程的其他地方应用更强的操作。
调试时,还要验证规则是否不匹配 Cloudflare 生成的路径,如 /cdn-cgi/*。
有关挑战相关行为的更多信息,请参阅规则故障排除和 Cloudflare WAF 故障排除。