Django の CSRF 対応

DjangoCSRF 対策を行う手順を調べたのでメモを残しておきます!
(今回は Django 1.2 を使用しました。 1.1から変更があるみたいですね)
(本家のチュートリアルを終わらせたくらいの人(私です)を対象にしています)


手順は2ステップ! シンプルですね〜

  1. POST を行うフォームで CSRF トークンを送信する
  2. POST 先のビューで CSRF トークンのチェックを行う

1.POST を行うフォームで CSRF トークンを送信する

これはフォームに {% csrf_token %} を含めることで実現できます。

<form action="" method="post">
  {% csrf_token %}
  ...
</form>

また、対応するビューで、 csrf_token が使用する変数を Context に設定する必要があります。

これを設定する方法は2つあります。

1. Context の代わりに RequestContext を使用する

RequestContext を使用すると、自動的に必要な変数が設定されます。

2. 手動で設定する

こんな風にするそうです(未確認)

from django.core.context_processors import csrf
def my_view(request):
    c = {}
    c.update(csrf(request))
    ....

※RequestContext とは


RequestContext は Context の派生クラスです。


Context との違いは以下のとおりです。

  1. 自動的に Context にいくつか変数が設定される


自動的に設定される変数は以下の2種類があります。

  1. TEMPLATE_CONTEXT_PROCESSORS に従って設定される変数
  2. django.core.context_processors.csrf によって設定される変数


render_to_response を使用している場合、context_instance 引数として RequestContext オブジェクトを渡します。

また、 direct_to_template を使用すると、少しお手軽に RequestContext を使えるみたいですね。
参考 http://it.kndb.jp/entry/show/id/1110

2.POST 先のビューで CSRF トークンのチェックを行う

これには2つの方法があります。1の方が漏れがないので、基本的にこちらを選ぶのがよさそうですね。

  1. CsrfViewMiddleware を使用する(デフォルト設定で使用するようになっています)。
  2. csrf_protect デコレータを、必要なビュー毎に使用する。

最後に♪

長々と書いてきましたが、Djangoの設定をいじっていなくて、すでに RequestContext を使っている場合、フォームに {% csrf_token %} を追加するだけで良さそうですね〜