我有一个包含3个表单的页面,每个表单都有一个Zend_Form_Element_Hash用于CSRF保护。

问题在于它们中的两个在CSRF上运行良好,但另一个在哈希上存在问题。

我第一次提交它时,它返回“ 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会导致什么?

顺便说一句,同一控制器在不同的动作中加载了两个表单(其中一个是有问题的表单)。 这可能是会议消失的原因吗?

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

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

好的,我找到了导致此问题的原因...问题是表单具有Ajax请求,并且当它们发生时,CSRF哈希值已过期(Hop = 1)。

有谁知道将表单用于CSRF + AJAX调用的解决方案?

===============>>#1 票数:0 已采纳

好的,我解决了此问题,然后在显示表单的Action和验证表单的Action中添加了CSRF元素,然后再保存到数据库中,而不是在Form类上创建CSRF元素

为了防止重复代码,我创建了此类:

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");

  ask by Cristiano Santos translate from so

未解决问题?本站智能推荐: