9

SymfonyでCSRF保護が有効になっているフォームをテストするための機能テストを作成する最良の方法は何ですか?

現在、各フォームを送信する前に、次のコードを追加する必要があります。

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

次に、$tokenと$token_nameを追加して、次のようなパラメーターを作成します。

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

ドキュメントで提案されているオプション:

'_with_csrf' => true,

まったく動作しません。

手動でテストされた各フォームにトークンを追加しないようにするためのより簡単な方法はありますか?または、テストの実行時にcsrfチェックをオフにする方法はありますか?

上記で説明した方法は、1〜2個のフォームをテストする必要がある場合は問題ありませんが、プロジェクトに10個の固有のフォームが含まれていると、面倒になります。

4

5 に答える 5

4

もちろん、URLを直接呼び出す場合は、_with_csrfオプションを使用できません。フォームページから送信ボタンをクリックしてパスする必要があります。そのようです:

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

文字列「signin」は、フォームに適合させる必要があります。'signin'の代わりに'form#myform input [type = "submit"]'のように、ラベルに依存しない文字列を使用して、フォームのIDを調整することもできます。

すでに提案したように、ログインのためにCSRFを無効にすることができます。これは、データを変更するフォームに非常に役立ちます。

于 2010-06-17T10:04:48.653 に答える
3

私は個人的に機能テストを広範囲に使用していませんが(おそらく私自身の不利益になります)、テストの目的でフォームクラスのCSRF保護をいつでもオフに切り替えることができます。

public function configure ()

  $this->disableLocalCSRFProtection();
于 2010-02-20T13:16:16.620 に答える
2

コンパイラパスを追加するだけで、すべてのフォームのcsrf保護を無効にできます。

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

または、configに追加して、フォーム拡張を完全に無効にすることができます。

framework:
    csrf_protection: false

ところで、最後の解決策は、フォームオプションを明示的に設定していない場合にのみ機能しますcsrf_protection

于 2016-03-02T12:03:30.003 に答える
0

テスト環境ではCSRFをオフにします。

于 2010-03-01T16:23:04.707 に答える
0

フォームを含むページを表示して、CSRFトークンを取得する必要があります。

$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');
于 2012-10-29T10:06:28.333 に答える