22
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Symfony2を使った、AJAX通信時のCSRFトークン検証

Last updated at Posted at 2013-04-19

Symfony2を使って、AJAX通信のクライアント側とサーバ側を構築する際に、CSRF(クロスサイトリクエストフォージェリ)を防ぐためのトークンをやりとりする方法。


まずは、クライアント側画面を出力するコントローラでは、csrf_providerをつかって、トークンを生成

DefaultController.php
<?php
class DefaultController extends Controller
{
    public function clientAction(Request $request)
    {
        $token = $this->get('form.csrf_provider')->generateCsrfToken('csrf_token');

        return $this->render('HogeFugaBundle:Default:client.html.twig', array(
                'csrf_token' => $token
        ));
    }
}

この csrf_token を、twigテンプレートのなかで、JavaScriptから利用可能なよう、変数にセットする。

client.html.twig
<script type="text/javascript">
    var csrf_token = '{{ csrf_token }}';
</script>

で、このトークンを、AJAX通信時にHTTPヘッダーに含めて一緒に送信するわけなんだけど、通信部分全部にこのトークンを使う処理を書くのは面倒なので、AJAX通信の送信イベントに、このトークンの付加処理をバインドする。

client.js
$(window).on('ajaxSend', function(elm, xhr, s) {
    xhr.setRequestHeader('X-CSRF-Token', csrf_token);
});

これを、サーバ側で受け取ってバリデーションする。

DefaultController.php
<?php
class DefaultController extends Controller
{
    public function serverAction(Request $request)
    {
        $token = $request->headers->get('X-CSRF-Token');

        if (false === $this->get('form.csrf_provider')->isCsrfTokenValid('csrf_token', $token)) {
            // エラー処理
        }
    }
}
22
22
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?