Get the CSRF token in test

After a long search (i've found nothing in doc and on the net about how to retrieve csrf token) i found a way:

$extract = $this->crawler->filter('input[name="element_add[_token]"]')
  ->extract(array('value'));
$csrf_token = $extract[0];

Extract the token from response before make the request.


CSRF token generator is normal symfony 2 service. You can get service and generate token yourself. For example:

    $csrfToken = $client->getContainer()->get('form.csrf_provider')->generateCsrfToken('registration');
    $crawler = $client->request('POST', '/ajax/register', array(
        'fos_user_registration_form' => array(
            '_token' => $csrfToken,
            'username' => 'samplelogin',
            'email' => '[email protected]',
            'plainPassword' => array(
                'first' => 'somepass',
                'second' => 'somepass',
            ),
            'name' => 'sampleuser',
            'type' => 'DSWP',
        ),
    ));

The generateCsrfToken gets one important parameter intention which should be the same in the test and in the form otherwise it fails.


In symfony 3, in your WebTestCase, you need to get the CSRF token:

$csrfToken = $client->getContainer()->get('security.csrf.token_manager')->getToken($csrfTokenId);

To get the $csrfTokenId, the best way would be to force it in the options of your FormType ():

class TaskType extends AbstractType
{
    // ...

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'csrf_token_id'   => 'task_item',
        ));
    }

    // ...
}

So in this case: $csrfTokenId = "task_item";. Or you you can try to use the default value, that would be the name of your form.

Then use it as a post parameter:

$client->request(
  'POST',
  '/url',
  [
    'formName' => [
      'field' => 'value',
      'field2' => 'value2',
      '_token' => $csrfToken
    ]
  ]
);