2012-03-01 26 views
14

Estoy escribiendo una prueba funcional y necesito hacer una solicitud posterior ajax. "El token de CSRF no es válido. Intente volver a enviar el formulario". ¿Cómo puedo obtener el token en mi prueba funcional?Obtener el token CSRF en la prueba

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

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

Respuesta

18

El generador de tokens CSRF es el servicio normal de Symfony 2. Puede obtener servicio y generar token usted mismo. Por ejemplo:

$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', 
     ), 
    )); 

El generateCsrfToken obtiene un parámetro importante intención que debe ser la misma en la prueba y en la forma de lo contrario se produce un error.

+0

¿Cómo se sabe cuál es el parámetro $ intention utilizado en los formularios? – bux

+0

puede usar cualquier $ intención que desee, solo asegúrese de que sea la misma que usa para verificar el token – Gigala

+3

En Symfony 3, el servicio devuelto por '-> get ('form.csrf_provider')' está en desuso. Use '-> get ('security.csrf.token_manager')' en su lugar. – iisisrael

11

Después de una larga búsqueda (no he encontrado nada en el documento y en la red acerca de cómo recuperar token CSRF) He encontrado una manera:

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

Extracto de la ficha de respuesta antes de hacer el solicitud.

+0

Esto funciona, pero depende de la finalidad de la prueba: si se trata de una prueba de comportamiento, replicando el comportamiento del navegador, entonces definitivamente es el camino a seguir (es lo que hace un navegador de todos modos); pero si se trata de una prueba de integración, verificando que el controlador se está integrando correctamente con el marco CSRF, entonces es bueno ir a través del administrador de tokens si es posible. –

5

En Symfony 3, en su WebTestCase, que necesita para obtener el token CSRF:

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

Para obtener el $csrfTokenId, la mejor manera sería to force it in the options de su FormType():

class TaskType extends AbstractType 
{ 
    // ... 

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

    // ... 
} 

Entonces en este caso: $csrfTokenId = "task_item";. O puede intentar usar el valor predeterminado, ese sería el nombre de su formulario.

luego usarlo como un parámetro de mensaje:

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

Esta es una respuesta contemporánea para symfony3 y debería ser más activamente votada. Combina información de la respuesta aceptada, sus comentarios y completa con la forma documentada de configuración '$ tokenId' –

Cuestiones relacionadas