我有一个包含3个表单的页面,每个表单都有一个用于CSRF保护的Zend_Form_Element_Hash。
问题在于其中2个与CSRF配合良好,但另一个在Hash中存在问题。
我第一次提交时,会返回“missingToken”错误。在那之后,如果我再次尝试提交它,它可以正常工作....
我创建了一个var_dump($ _ SESSION)来查看发生了什么,输出是:
在视图中(创建表单时):
array(7) {
...
["__ZF"]=>
array(3) {
["Zend_Form_Element_Hash_routeSearch_csrf"]=>
array(2) {
...
}
["Zend_Form_Element_Hash_registration_csrf"]=>
array(2) {
...
}
["Zend_Form_Element_Hash_login_csrf"]=>
array(2) {
...
}
}
["Zend_Form_Element_Hash_routeSearch_csrf"]=>
array(1) {
["hash"]=>
string(32) "2e348e982e5d8849a7bcb3f42fdd6c0d"
}
["Zend_Form_Element_Hash_registration_csrf"]=>
array(1) {
["hash"]=>
string(32) "6fd74223bb158cc3cc780ee29b26ae58"
}
["Zend_Form_Element_Hash_login_csrf"]=>
array(1) {
["hash"]=>
string(32) "d07dc1ac514082f1960c300670414399"
}
}
提交后:
array(6) {
...
["__ZF"]=>
array(2) {
["Zend_Form_Element_Hash_login_csrf"]=>
array(2) {
...
}
["Zend_Form_Element_Hash_routeSearch_csrf"]=>
array(2) {
...
}
}
["Zend_Form_Element_Hash_login_csrf"]=>
array(1) {
["hash"]=>
string(32) "d07dc1ac514082f1960c300670414399"
}
["Zend_Form_Element_Hash_routeSearch_csrf"]=>
array(1) {
["hash"]=>
string(32) "b9378bec2fd18cf232f451ed602acf0a"
}
}
如您所见,“Zend_Form_Element_Hash_registration_csrf”已经消失......
我尝试了所有我知道的但没有找到什么可以让会话消失......有什么想法吗? Zend会导致什么原因?
顺便说一句,其中两个表单由不同的Action中的同一个Controller加载(其中一个是有问题的表单)。这可能是会议消失的原因吗?
请帮助,因为我不知道该怎么做才能找到问题......我被困在这里= S.
------编辑------
好的,我找到了导致这种情况的原因......问题是表单有Ajax请求,当它们发生时,CSRF Hash到期(Hop = 1)。
任何人都知道使用带有CSRF + AJAX调用的表单的解决方案吗?
答案 0 :(得分:0)
好的,我解决了在Action中添加CSRF元素,它显示了表单,并在Action中验证了它,然后保存到数据库,而不是在我的Form Class上创建它
为了防止重复代码,我创建了这个类:
class Application_Model_CSRF{
public static function createCSRF($form, $csrf_salt_name, $field_name="csrf") {
$element=$form->createElement('hash', $field_name,array(
'salt' => $csrf_salt_name
));
//Create unique ID if you need to use some Javascript on the CSRF Element
$element->setAttrib('id',$form->getName().'_'.$element->getId());
$form->addElement($element);
return $element;
}
}
然后,在显示表单的Action中以及在其验证的其他Action中,我使用此代码:
$form = new Application_Form_Account_Registration();
Application_Model_CSRF::createCSRF($form,"registration");