2011-12-11 53 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");