I have created a Symfony2 form and bound it to the Request. I need to explicitly ensure whether the CSRF token is valid/invalid before proceeding with the rest of the form.
$form['_token']->isValid()
throws OutOfBoundsException
with message "Child _token does not exist."
I can still verify that the rendered form contains _token
field. In case that CSRF value is invalid, $form->isValid()
returns false.
What am I missing here?
Update 1:
Controller (partial):
private function buildTestForm() {
$form = $this->createFormBuilder()
->add('name','text')
->getForm();
return $form;
}
/**
* @Route("/test/show_form", name="test.form.show")
* @Method("GET")
*/
public function showFormTest()
{
$form = $this->buildTestForm();
return $this->render('TestBundle::form_test.html.twig', array('form' => $form->createView()));
}
/**
* @Route("/test/submit_form", name="test.form.submit")
* @Method("POST")
*/
public function formTest()
{
$form = $this->buildTestForm();
$form->bind($this->getRequest());
if ($form['_token']->isValid()) {
return new Response('_token is valid');
} else {
return new Response('_token is invalid');
}
}
Template
{# Twig template #}
<form action="{{ path('test.form.submit') }}" method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<input type="submit" name="go" value="Test Form" />
</form>
In addition to artworkad, you can specify an intention:
Twig:
PHP:
Or not:
Twig:
PHP:
Another way (if you prefer DI) to validate token outside of controller (e.g. in listener):
I am not sure of this but have you tried the validator on an unmapped field:
There is no documented way to check csrf token manually. Symfony automatically validates the presence and accuracy of this token. http://symfony.com/doc/current/book/forms.html#csrf-protection
However there is a csrf provider:
http://api.symfony.com/2.0/Symfony/Component/Form/Extension/Csrf/CsrfProvider/SessionCsrfProvider.html
and
http://api.symfony.com/master/Symfony/Component/Form/Extension/Csrf/CsrfProvider/DefaultCsrfProvider.html
You can retrieve the provider like this
use can then use
You need to finde out the intention string used by your form.
Some interesting posts on SO:
Symfony CSRF and Ajax
Symfony2 links with CSRF token