2011-12-11 98 views
0

我有一个包含3个表单的页面,每个表单都有一个用于CSRF保护的Zend_Form_Element_Hash。表单提交后Zend哈希会话变量丢失

问题是,其中2个与CSRF一起工作良好,但另一个与Hash有问题。

我第一次提交它时,会返回“missingToken”错误。在此之后,如果我尝试重新提交它,它工作正常....

我做了一个的var_dump($ _ SESSION),看看发生了什么事情输出功率为:

在View(当创建表格):

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可能导致什么?

顺便说一下,其中2个表单由不同的Actions中的相同控制器加载(其中一个是有问题的表单)。会不会是会话消失的原因?

请帮忙,因为我不知道该怎么办才能找到问题......我卡在这里= S。

------编辑------

好吧,我发现......问题是什么原因造成这样的形式有Ajax请求,并发生时,该CSRF哈希到期(Hop = 1)。

任何人都知道使用CSRF + AJAX调用表单的解决方案吗?

回答

0

好吧,我解决了这个添加CSRF元素,显示了形式操作,并在保存到数据库之前验证它的行动,而不是在我的Form类

创建它以防止重复代码中,我创建了这个类:

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; 
    } 

} 

然后,在显示的形式操作,并在它的验证的其他动作,我用这个代码:

$form = new Application_Form_Account_Registration(); 
Application_Model_CSRF::createCSRF($form,"registration");