Переменная сеанса Zend Hash потеряна после отправки формы
У меня есть страница, которая содержит 3 формы, каждая с Zend_Form_Element_Hash для защиты CSRF.
Проблема в том, что 2 из них хорошо работают с 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 может вызвать это?
Кстати, 2 формы загружаются одним и тем же контроллером в разных действиях (одна из них - форма с проблемами). Может ли это быть причиной того, что сеанс исчезает?
Пожалуйста, помогите, потому что я больше не знаю, что делать, чтобы найти проблему... Я застрял здесь = S.
------ РЕДАКТИРОВАТЬ ------
Хорошо, я нашел причину этого... Проблема в том, что у формы есть Ajax-запросы, и когда они происходят, хэш CSRF истекает (Hop=1).
Кто-нибудь знает решение использовать форму с вызовами CSRF + AJAX?
1 ответ
Хорошо, я решил это, добавив элемент 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");