Существует какой-то способ в Symfony 2 для создания токена CSRF при каждом рендеринге формы? В моем контроллере я пытался что-то вроде этого:Создать токен CSRF в зависимости от даты и времени
$request = $this->get('request');
if ($request->getMethod() != 'POST') {
$csrf = $this->get('form.csrf_provider');
$date= new \DateTime("now");
$this->date = $date->format('Y-m-d H:i:s');
$token = $csrf->generateCsrfToken($this->date);
} elseif($request->getMethod() == "POST") {
$csrf = $this->get('form.csrf_provider');
$token = $csrf->generateCsrfToken($this->date);
}
$form = $this->createFormBuilder()
....
->add('_token','hidden',array(
'data' => $token
))->getForm();
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
DO something
}
}
всего времени находится в моем запросе права маркера хэша. Но после bindRequest его изменение хэша по умолчанию, генерируемого из строки безопасности в параметрах.ini, и isValid метод возвращает, конечно, FALSE-ответ. Существует какой-то способ, как его настроить?
EDIT В ответ на theunraveler ответ, я редактировал свой контроллер и создать мой провайдер CSRF, но все-таки им адресности «Маркер CSRF недействителен. Пожалуйста, попробуйте повторно отправить форму» ошибку. Мой провайдер CSRF выглядит следующим образом:
namespace My\Namespace;
use Symfony\Component\HttpFoundation\Session;
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
class MyCsrfProvider implements CsrfProviderInterface
{
protected $session;
protected $secret;
protected $datetime;
public function __construct(Session $session, $secret)
{
$this->secret = $secret;
$this->datetime = new \DateTime('now');
$this->session = $session;
}
public function generateCsrfToken($intention)
{
return sha1($this->secret.$intention.$this->datetime->format('YmdHis').$this->getSessionId());
}
public function isCsrfTokenValid($intention, $token)
{
return $token === $this->generateCsrfToken($intention);
}
protected function getSessionId()
{
return $this->session->getId();
}
}
Чем я добавить config.yml класс обслуживания:
services:
form.csrf_provider:
class: My\Namespace\MyCsrfProvider
arguments: [ @session, %kernel.secret% ]
и контроллер я изменяю это:
//any form without _token field
$form = $this->createFormBuilder()
->add('field1')
->add('field2')->getForm()
if ($this->getRequest()->getMethod() == 'POST') {
$request = $this->getRequest();
$form->bindRequest($request);
if ($form->isValid()) {
Do something
return $this->redirect($this->generateUrl('somewhere'));
}
}
Cant быть проблема в секундах в моем хеше? Если я удаляю секунды из формата даты, вы можете использовать его, но с истечением 1 мин, а это не очень хорошее решение. Я думаю, причина в том, что время изменилось.
Неужели никто с некоторыми намеками? – gavec
Вы могли решить это? – JohnnyQ