2010-02-20 13 views
9

Was ist der beste Weg zum Erstellen von Funktionstests zum Testen von Formularen mit aktiviertem CSRF-Schutz in Symfony?Funktionsprüfungsformular mit aktiviertem CSRF in Symfony

Zur Zeit habe ich den folgenden Code vor jedem Formular submittion hinzufügen:

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

Dann füge ich die $ Token und $ token_name Parameter wie folgt zu bilden:

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

Die Option vorgeschlagen in die Dokumentation:

'_with_csrf' => true, 

funktioniert überhaupt nicht.

Gibt es eine einfachere Möglichkeit, das Hinzufügen eines Tokens zu jedem manuell getesteten Formular zu vermeiden? Oder gibt es eine Möglichkeit, csrf-Überprüfung zu deaktivieren, wenn Tests ausgeführt werden?

Der Weg, den ich oben beschrieben habe, ist in Ordnung, wenn Sie 1-2 Formulare testen müssen, aber wenn das Projekt zig eindeutige Formulare enthält, wird es ein Schmerz.

+0

T Die Dokumentationsoption verwendet eine Instanz von BaseForm zum Erweitern von; Das CSRF-Token wird jedoch unter Verwendung der Art des Formulars generiert, also MyFooForm! = BaseForm und deshalb schlägt die Option fehl ... Ihre Option ist die Art, wie ich es auch in meinen Projekten getan habe. – richsage

+0

Es gibt einen anderen Grund, warum es auch nicht funktioniert. Es fügt das csrf-Token zur Liste der Parameter hinzu, aber normalerweise in Formularen in Arrays (wie im obigen Beispiel). So ist es völlig nutzlos :-(. Danke für Ihren Kommentar. – Stepashka

Antwort

4

Natürlich können Sie die Option _with_csrf nicht verwenden, wenn Sie die URL direkt aufrufen. Sie müssen von der Formularseite aus auf die Übermittlungsschaltfläche klicken. Wie so:

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

Der String 'signin' muss auf dem Formular angepasst werden. Sie können auch eine labelunabhängigere Zeichenfolge verwenden, z. B. 'form # myform input [type = "submit"]' anstelle von 'signin', und die ID Ihres Formulars anpassen.

Wie bereits vorgeschlagen, können Sie CSRF für die Anmeldung disaple, es ist wirklich nützlich für Formulare, die Daten ändern.

3

Ich persönlich benutze keine Funktionstests, die extensiv sind (wahrscheinlich zu meinem eigenen Nachteil), aber Sie könnten den CSRF-Schutz immer in Ihrer Formularklasse für Testzwecke ausschalten.

public function configure() 

    $this->disableLocalCSRFProtection(); 
0

Ich würde CSRF für Testumgebung deaktivieren.

0

Sie sollten ein CSRF-Token erhalten, indem Sie die Seite mit dem Formular anzeigen.

$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

Sie können csrf Schutz für alle Formen nur durch Hinzufügen zusätzlicher Compiler Pass deaktivieren:

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); 
     } 
    } 
} 

Oder Sie können, indem zu Config vollständig Form Erweiterung deaktivieren:

framework: 
    csrf_protection: false 

btw, letzte Lösungen funktionieren nur, wenn Sie die Formularoption csrf_protection nicht explizit eingestellt haben