web-dev-qa-db-ja.com

symfony CSRFとAjax

私のSymfony 2プロジェクトにいくつかのajax機能を実装しようとしています。 jqueryの$ .postを使用して、一部のデータをコントローラーに送り返します。ただし、POSTデータの場合、symfonyのcsrf保護はフォームにのみ適用されるように見えるので、CSRF保護は設定されていません。

これを実装する簡単な方法は何でしょうか?

フォームを使用するときは、$ form-> isValid()を実行して、CSRFトークンが渡されるかどうかを確認できます。私は現在、必要なすべてをPOST=フォームに配置してから投稿しています。これは、基本的に、そのフォームを使用してCSRF保護を実装することだけを意味します。

27
peterrus

Symfony2では、CSRFトークンはデフォルトでセッションに基づいています。生成したい場合は、このサービスを取得して生成メソッドを呼び出すだけです。

//Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider by default
$csrf = $this->get('form.csrf_provider');
//Intention should be empty string, if you did not define it in parameters
$token = $csrf->generateCsrfToken($intention); 

return new Response($token);

この質問 はあなたに役立つかもしれません

27
Vitalii Zurian

私は断続的にこの問題を抱えていました。それは私のajaxが原因ではないことがわかりましたが、Silexが非推奨のDefaultCsrfProviderを提供しているため、セッションID自体をトークンの一部として使用し、セキュリティのためにIDをランダムに変更しています。代わりに、新しいCsrfTokenManagerを使用するように明示的に指示すると、トークンが生成されて保存されるため、修正されますinセッションの有効性に影響を与えずにセッションIDを変更できますトークン。

/** Use a CSRF provider that does not depend on the session ID being constant. We change the session ID randomly */
$app['form.csrf_provider'] = $app->share(function ($app) {
    $storage = new Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage($app['session']);
    return new Symfony\Component\Security\Csrf\CsrfTokenManager(null, $storage);
});
2
Josh Ribakoff

このスニペットを試してみてください。 symfonyフォームはpostリクエストで送信される特別な_csrf_tokenを生成する必要があります。この値がないと、セキュリティ警告が発生します。

もちろん#targetFormはフォームIDに、/ endpointはターゲットajax urlに置き換えてください。

$('#targetForm').bind('submit', function(e) {

    e.preventDefault();
    var data = $(this).serialize();

    $.post('/endpoint', data, function(data) {
        // some logic here
    });

});
1