Получить токен CSRF в тесте - PullRequest
15 голосов
/ 02 марта 2012

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

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

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

Ответы [ 3 ]

20 голосов
/ 06 марта 2013

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

    $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 получает один важный параметр намерение , который должен быть одинаковым в тесте и в форме, иначе он завершится неудачей.

12 голосов
/ 02 марта 2012

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

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

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

5 голосов
/ 29 июля 2016

В 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";. Или вы можете попробовать использовать значение по умолчанию, которое будет именем вашей формы.

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

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