Получить токен CSRF в тесте

Я пишу функциональный тест, и мне нужно сделать запрос AJAX post. " недопустимый маркер CSRF. Пожалуйста, попробуйте повторно отправить форму". Как я могу получить токен в своем функциональном тесте ?

$crawler = $this->client->request(
  'POST', 
  $url, 
  array(
      'element_add' => array(
          '_token' => '????',
          'name'   => 'bla',
      )

  ), 
  array(), 
  array('HTTP_X-Requested-With' => 'XMLHttpRequest')
);

3 ответов


генератор токенов CSRF-это обычный сервис symfony 2. Вы можете получить обслуживание и создать token самостоятельно. Например:

    $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' => 'sample@fake.pl',
            'plainPassword' => array(
                'first' => 'somepass',
                'second' => 'somepass',
            ),
            'name' => 'sampleuser',
            'type' => 'DSWP',
        ),
    ));

на generateCsrfToken получает один важный параметр намерение, который должен быть одинаковым в тесте и в форме в противном случае он завершается.


после долгого поиска (я ничего не нашел в doc и в сети о том, как получить токен csrf) я нашел способ:

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

извлеките маркер из ответа перед выполнением запроса.


в symfony 3, в вашем WebTestCase, вам нужно получить токен CSRF:

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

для получения $csrfTokenId, лучший способ был бы чтобы заставить его в опциях вашего FormType ():

class TaskType extends AbstractType
{
    // ...

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

    // ...
}

таким образом: $csrfTokenId = "task_item";. Или вы можете попробовать использовать значение по умолчанию, это будет имя вашей формы.

затем используйте его в качестве параметра post:

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