如何使用反向代理缓存表单并处理过时的表单令牌?


8

Form API生成表单时,它还会生成一个令牌,该令牌与该表单一起在隐藏字段中传递出去,并有望返回。如果是,将处理该表单。

如果渲染的表单曾经被Varnish缓存过,则该机制就会中断。提交表单的第一个用户将使用令牌,并且随后尝试使用该表单的请求将被拒绝。

有哪些策略可用于在缓存其呈现的表单时保持其正常工作?


你确定吗?我用表单和反向代理构建了站点,但是没有看到问题。通常,您唯一需要注意的就是确保结果页面不会被缓存。
阿尔弗雷德·阿姆斯特朗

我希望证明自己是错误的,因为这可以解决我的问题,但是是的,我确定。:)检查form_ {g,s} et_cache函数以获取详细信息。
Letharion

对于匿名用户,我确信可以安全地缓存带有表单的页面。对于非匿名用户,无论如何反向代理都是有问题的。
阿尔弗雷德·阿姆斯特朗

2
(仅当用户具有ID时才生成令牌。)
Alfred Armstrong

1
嗯,那很有道理。不幸的是,在这种情况下,我的用户已通过身份验证。也许应该重新措词以包括这个问题。
Letharion

Answers:


5

我在网站上使用BOA,但默认情况下,BOA只是为表单提交即时禁用了前端缓存。除了我的实际经验之外,我还碰到了一个只有一岁的人,他讲述了《新西兰邮报》如何处理Drupal&Varnish和表单令牌问题。真正的John Wayne,它是Drupal缓存必读的书。仅关注表单问题:

难题的最后一部分是Cookie缓存绕过高级模块,该模块会在用户每次在网站上提交POST表单时自动设置特殊的NO_CACHE cookie,其中包括登录表单。我们的Varnish配置为在看到Cookie时绕过页面缓存(而不是ESI缓存)。

当在form_alter(unset($ form ['#token']);)或($ form ['#token'] = FALSE;)中不需要XSRF生产时,也可以禁用表单令牌。

Acquia Drupal的性能文章提出了Drupal模块Authcache,但是阅读了Authcache上的文档,它使用表单占位符计算了缓存(不缓存表单):

Authcache尝试拦截任何自定义的内容并在HTML中设置占位符。然后,在加载页面之后,将使用Ajax回调检索自定义数据并填写占位符,以动态更新页面HTML。

当前的Authcache占位符:表单令牌(仅已登录的用户; Drupal要求提供,以防止跨站点请求伪造攻击)

策略是,缓存除form之外的所有内容。那么解决所有其他问题:也许根本不使用Varnish,Memcache和Redis?我的策略是使用BOA提供的功能,因为我使用BOA并且其背后的向导(omega8.cc)比我了解的更多。我不认为有外部缓存可以解决问题。他们似乎都绕过了表格。

使用前面提到的authcache以及经过微调的“视图和面板”进行部分缓存,如NZ Post文章中所述,并由Wunderkraut的大脑信任组织描述过 -它已经过时了,但是解决了这个问题。

使用Drupal ESI模块,并且Varnish部分符合ESI):

ESI(或Edge Side Includes)是针对身份验证用户的高性能缓存解决方案,但对匿名用户也有帮助。

通常,对经过身份验证的用户进行个性化设置的页面(即使是较小的个性化设置,例如显示“ Manarth登录”的代码块)也可以防止反向代理(其执行速度可能比Drupal快100倍),这是因为消息然后可以被另一用户看到为一个用户准备的内容。

希望那对您有所帮助。


快速浏览一下代码表明ESI模块在表单验证方面根本不做任何事情。没有提及令牌处理,也没有任何有趣的形式更改。是否有可能您根本没有在清漆中缓存任何需要身份验证的表格,这就是为什么您从未见过此问题?
Letharion

事实证明,这正是发生的情况,BOA绕过了表单的动态缓存(很抱歉,我之前的回答不完整/错误)。现在,即使没有直接解决,ESI仍然是我的答案中“缓存所有内容”策略的重要组成部分。
汤姆,

新西兰的那篇文章确实非常有趣。但是,据我所知,它仅通过以下方式解决令牌问题:“在您确定XSRF保护不重要的情况下……Drupal提供了一种禁用表单令牌的机制”,这在以下方面没有帮助:我的情况。
Letharion

尽管有很多有用的信息,而且肯定还有其他人可以将其应用于他们的问题。+1,而且仅剩一个小时,所以我也可能会意识到赏金。:)
Letharion

0

一种可能的解决方案是将令牌与一起全部禁用$form[‘#token’] = FALSE;,然后覆盖提交回调,而不是实际发布评论,使用令牌重新生成原始表单,然后要求用户确认该帖子。

如果用户支持ECMAScript,则可以通过拥有一种服务资源来改善用户体验,该资源公开新表单令牌的表单生成并将相关表单插入form_cache。然后,一旦用户将注意力集中在表单上,​​并因此可能想要提交,就禁用提交按钮,获取新令牌并将其插入已呈现的表单中,然后再次启用提交按钮。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.