2012-03-01 11 views
14

私は機能テストを書いています。私はajax投稿要求をする必要があります。 "CSRFトークンが無効です。フォーム「」を再送信してください。どうすれば機能テストでトークンを入手できますか?テストでCSRFトークンを取得

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

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

答えて

18

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' => '[email protected]', 
      'plainPassword' => array(
       'first' => 'somepass', 
       'second' => 'somepass', 
      ), 
      'name' => 'sampleuser', 
      'type' => 'DSWP', 
     ), 
    )); 

generateCsrfTokenは、テスト中に、フォームで同じでなければなりません意思がそうでなければ、それが失敗した一つの重要なパラメータを取得します。 symfonyの3で

+0

フォームに使用されている$ intentionパラメータは何ですか? – bux

+0

あなたは任意の$意思を使用できます。トークンのチェックにも同じものを使用してください。 – Gigala

+3

symfony 3では、 ' - > get( 'form.csrf_provider')'によって返されるサービスは非推奨です。代わりに ' - > get( 'security.csrf.token_manager')'を使用してください。 – iisisrael

11

は長い検索(私はドキュメントで何も見つからないし、CSRFトークンを取得する方法について、ネット上でました)後、私は方法を見つけた:

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

が応答からトークンを抽出する前に作ります要求。

+0

が、それは試験の目的によって異なります:

その後ポストパラメータとしてそれを使用することはブラウザの動作を複製する行動試験、だならば、それは間違いなく行く方法です(とにかくブラウザのようなものです)。それが統合テストの場合は、コントローラをチェックすることがCSRFフレームワークと正しく統合されています。可能であれば、トークンマネージャーを経由することをお勧めします。 –

5

、あなたのWebTestCaseに、あなたはCSRFトークンを取得する必要があります。

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

$csrfTokenIdを取得するために、最善の方法は、あなたのFormTypeto force it in the options(だろう):

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 
    ] 
    ] 
); 
+0

これは現代的なsymfony3の答えであり、より積極的にアップビューされるべきです。それは、受け入れられた答え、そのコメントと完了からの情報と、 '$ tokenId'を設定するための文書化された方法 –

関連する問題