![](/img/trans.png)
[英]How can validate multiple form In one page using form token to prevent CSRF Attacks?
[英]Zend Form - multiple forms in one page and (CSRF) token validations
我使用 Zend-Form 在我的项目中生成我的 forms。
第一:如何处理同一页面上多个forms,只post提交的表单?
第二:当我在同一页面上有两个 forms 时,令牌将仅验证 HTML 中最顶层呈现的表单。 第二个表单出现“令牌不匹配”错误,从而使表单无法发布。 你如何给每个表单一个不与其他表单冲突的唯一令牌?
真诚的,为什么
当我在同一页面上有两个 forms 时,令牌将仅验证 HTML 中最顶部的呈现形式。 第二个表单出现“令牌不匹配”错误,从而使表单无法发布。 你如何给每个表单一个不与其他表单冲突的唯一令牌?
当前实现无法使用多个 forms 上的令牌(请参阅initCsrfValidator
)。
我建议您生成自己的令牌,将其存储在 session(带有表单 ID)中并自行验证。
我在尝试使用Zend_Form_Element_Hash
在同一页面上有两个 forms 时发现了这个问题。 有两种方法可以做到这一点, 文档中都提到了这两种方法:
hash 元素的名称应该是唯一的。 我们建议对元素使用 salt 选项 - 两个具有相同名称和不同盐的哈希不会发生冲突
所以...
Hash
元素使用唯一名称Hash
元素使用唯一的盐值实际上,我刚刚修复了一个类似的问题,即我生成了具有 csrf 保护的相同表单的多个副本。 发生的事情是只有最后一个创建的表单具有正确的 csrf 令牌。
处理这个问题的草率方法是更改 Zend 库中的跃点(在 Zend_Form_Element_Hash 文件中),以便令牌在 1 次刷新或页面加载后不会过期。 这是解决问题的一种非常简单的方法,但只有在您知道页面将加载多少次时才有效。 这是创可贴解决方案
正确的方法是在页面加载后执行 ajax 调用以获取新的刷新令牌。 然后使用您的 javascript 库(jquery 可能是最简单的)并找到令牌的所有实例并将它们全部替换为新的。
所以就代码而言,它看起来像这样:Controller:
$form->hash->initCsrfToken();
$this->view->hash = $form->hash->getValue();
在您的 js 文件中(如果您使用的是 jquery)
$(.hash).replaceWith('HiddenHtmlPart1'.=hash.'HiddenHtmlPart2'); 重要的部分是选择器到 select 的所有隐藏元素。 然后你只需要替换隐藏元素的内部。 相同的想法适用于其他 js 库,尽管它会涉及不同的方法。
我遇到了同样的情况
当我在同一页面上有两个 forms 时,令牌将仅验证 HTML 中最顶部的呈现形式。 第二个表单出现“令牌不匹配”错误,从而使表单无法发布。 你如何给每个表单一个不与其他表单冲突的唯一令牌?
一种可能的解决方案是使用单独的表单仅用于令牌生成和验证。 然后在 HTML 中,每个表单都有自己的标记元素,但具有相同的值。 如果您提交一个表单,则使用您用于生成它的表单验证此令牌元素。 如果您混合使用 ajax 表单和经典 POST 表单,那么您可以在响应中发送一个新令牌并将其分配给每个令牌元素。
//Finally set the response token
$form->getElement('token')->render(); //Need to call render in order to regenerate the token
$response['token'] = $form->getElement('token')->getValue();
$this->_helper->json($response);
在 jquery 中,您可以使用 $('._token').val(response.token)
事实上,这比必须向每个表单添加 Zend_Form_Element_Hash 非常简单,甚至更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.