2012-03-01 13 views
14

Piszę test funkcjonalny i muszę wysłać prośbę o dodanie do ajax. "Token CSRF jest nieprawidłowy. Spróbuj ponownie przesłać formularz". Jak mogę uzyskać token w moim teście funkcjonalnym?Zdobądź token CSRF w teście

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

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

Odpowiedz

18

Generator tokenów CSRF to normalna usługa symfony 2. Możesz sam uzyskać serwis i wygenerować token. Na przykład:

$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 dostaje jeden ważny parametr zamiar które powinny być takie same w teście iw postaci inaczej to się nie powiedzie.

+0

Jak wiadomo, jaki jest parametr zamiaru $ używany w formularzach? – bux

+0

możesz użyć dowolnej intencji, którą chcesz, po prostu upewnij się, że jest to ta sama, której używasz również do sprawdzania tokena – Gigala

+3

W Symfony 3, usługa zwrócona przez '-> get ('form.csrf_provider')' jest przestarzała. Zamiast tego użyj '-> get ('security.csrf.token_manager'). – iisisrael

11

Po długich poszukiwaniach (i już nic w dokumencie oraz w internecie na temat sposobu pobierania tokena CSRF znaleźć) znalazłem sposób:

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

wyodrębnić tokenu z odpowiedzi przed dokonaniem żądanie.

+0

To działa, ale to zależy od celu badania: czy jest to test behawioralny, replikacji zachowanie przeglądarki, to na pewno jest do zrobienia (to jest to, co i tak robi przeglądarka); ale jeśli jest to test integracyjny, sprawdzenie, czy kontroler prawidłowo integruje się ze strukturą CSRF, dobrze jest przejść przez menedżera tokenów, jeśli możesz. –

5

W Symfony 3, w WebTestCase, musisz uzyskać token CSRF:

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

aby uzyskać $csrfTokenId, najlepszym sposobem byłoby to force it in the options z Twojego FormType():

class TaskType extends AbstractType 
{ 
    // ... 

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

    // ... 
} 

W tym przypadku: $csrfTokenId = "task_item";. Lub możesz spróbować użyć wartości domyślnej, która byłaby nazwą twojego formularza.

następnie użyć go jako parametr postu:

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

To jest współczesna odpowiedź dla symfony3 i powinna być bardziej aktywnie przejęta. Łączy informacje z zaakceptowanej odpowiedzi, komentarze i kończy się z udokumentowanym sposobem ustawienia '$ tokenId' –

Powiązane problemy