2010-02-20 7 views
9

¿Cuál es la mejor forma de crear pruebas funcionales para probar formularios con la protección CSRF habilitada en Symfony?Formulario de prueba funcional con CSRF habilitado en Symfony

Actualmente tengo que añadir el siguiente código antes de cada forma submittion:

$form = new sfGuardFormSignin(); 
    $token = $form->getCSRFToken(); 
    $token_name = $form->getCSRFFieldName(); 

Luego añadir los $ token y $ token_name para formar parámetros como este:

call('/login', 'POST', array (
    'signin' => 
    array (
     'username' => $username, 
     'password' => $password, 
     $token_name => $token, 
    ))) 

La opción sugerida en la documentación:

'_with_csrf' => true, 

No funciona en absoluto.

¿Hay alguna manera más simple de evitar agregar tokens a cada formulario probado manualmente? ¿O hay una manera de desactivar la comprobación de csrf cuando se ejecutan las pruebas?

La forma en que he descrito anteriormente está bien cuando tienes que probar 1-2 formularios, pero si el proyecto contiene decenas de formas únicas, se convierte en un problema.

+0

T La opción de documentación utiliza una instancia de BaseForm para extender desde; Sin embargo, el token CSRF se genera utilizando el tipo de formulario, por lo que MyFooForm! = BaseForm y, por lo tanto, esa es la razón por la cual la opción falla ... tu opción es la forma en que terminé haciéndolo también en mis proyectos. – richsage

+0

Hay otra razón por la que falla también. Agrega el token csrf a la lista de parámetros, pero generalmente en formas está en matrices (como en el ejemplo anterior). Por lo tanto, es completamente inútil :-(. Gracias por su comentario. – Stepashka

Respuesta

4

Por supuesto, no puede usar la opción _with_csrf si llama directamente a la url. Debe pasar desde la página del formulario, haciendo clic en el botón Enviar. Al igual que :

click('signin', array('signin' => array('username' => $username, 'password' => $password), array('_with_csrf' => true))) 

La cadena 'signin' debe adaptarse a su forma. También puede usar una cadena más independiente de la etiqueta, como 'form # myform input [type = "submit"]' en lugar de 'signin', adaptando la identificación de su formulario.

Como ya se ha sugerido, puede desactivar el CSRF para iniciar sesión, es realmente útil para los formularios que modifican los datos.

3

Personalmente, no utilizo las pruebas funcionales de manera exhaustiva (probablemente en mi propio perjuicio), pero siempre se puede desactivar la protección CSRF en su clase de formulario para fines de prueba.

public function configure() 

    $this->disableLocalCSRFProtection(); 
0

Desactivé CSRF para entorno de prueba.

0

Debe obtener un token de CSRF mostrando la página que incluye el formulario.

$browser->get('/login'); 
$dom = new DOMDocument('1.0', $browser->getResponse()->getCharset()); 
$dom->loadHTML($browser->getResponse()->getContent()); 
$domCssSelector = new sfDomCssSelector($dom); 
$token = $domCssSelector->matchSingle('input[name="_csrf_token"]')->getNode()->getAttribute('value'); 
1

Puede desactivar la protección CSRF para todas las formas simplemente añadiendo pase adicional de compilador:

class CsrfProtectionCompilerPass implements CompilerPassInterface 
{ 
    /** 
    * {@inheritdoc} 
    */ 
    public function process(ContainerBuilder $container) 
    { 
     $env = $container->getParameter('kernel.environment'); 
     if ($env == 'test') { 
      $container->setParameter('form.type_extension.csrf.enabled', false); 
     } 
    } 
} 

O Puede desactivar la extensión formulario en su totalidad mediante la adición de config:

framework: 
    csrf_protection: false 

por cierto, La última solución funciona solo si no ha configurado explícitamente la opción de formulario csrf_protection

Cuestiones relacionadas