記事ページを表示中

axiosでCSRFトークンをDjangoに返す

記事No.62

更新日時2023年02月18日

DjangoのCSRF対策機能

DjangoはCSRF対策機能を持っています。

クライアントに、フォームが入ったページを返す際(レスポンスの際)にDjangoはCSRFトークンを発行します。

フォームからDjangoにデータを送り返す際に、このCSRFトークンも一緒に送り返す事で、DjangoはCSRF攻撃されていないと判断します。

コメントフォーム

axiosでCSRFトークンを返す場合は、cookieを使用する

axiosを使用して非同期通信を行いたい場合、cookieを使うと便利です。

同期通信の場合、CSRFトークンの設定は以下のようになります。

<form action="/example/" method="post">
    {% csrf_token %}
    <input type="text" name="search">
    <input type="submit" value="送信する">
</form>
<!-- {% csrf_token %}の部分はDjangoでレンダリングされるとCSRFトークン入りのinput要素になります -->

同期通信の場合「送信する」のボタンをクリックすると、CSRFトークンが、HTTPリクエストヘッダに格納され、Djangoに送られます。

一方、axiosを使用した非同期通信の場合、フォームに設置したCSRFトークンを使用するよりも、cookieに保存されているCSRFトークンを使用すると便利です。

<!doctype html>
<html lang="ja">
   <head>
      <!-- ヘッダ情報 -->
   </head>
   <body>
      <!-- ボディ情報 -->
      {% csrf_token %}
   </body>

HTMLファイルの任意の場所に、{% csrf_token %}を記述します。

この記述は、Djangoがレンダリングすると、

<input type=”hidden” name=”csrfmiddlewaretoken” value=”example”>

となり、クライアントにCSRFトークンを渡しています。

更に、この記述をする事で、クライアントにページを送る際にHTTPレスポンスのcookieにCSRFトークンを格納しています。

非同期通信の場合、このcookieに保存されたCSRFトークンをDjangoに送り返します。

//Vue.jsで設定する場合
methods: {
   returnCsrfToken(){
      axios.defaults.xsrfCookieName = 'csrftoken'
      axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'
      axios({
         method: 'POST',
         url: example.com
         data: {example:exampleData}
      })
      .then(response => {
         console.log('トークンを送った')
      })
   }
},
//以下2行を追記する事でクッキーに保存されているCSRFトークンがHTTPリクエストヘッダに格納される
//axios.defaults.xsrfCookieName = 'csrftoken'
//axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'

コメントフォーム

同期、非同期問わず、{% csrf_token %}は必要

以上のように、HTMLファイルに、{% csrf_token %}の記述をする事で、Djangoは、HTTPレスポンスヘッダと、HTTPレスポンスボディの両方にCSRFトークンを格納します。

あとは、Djangoから送られてきたCSRFトークンを、送り返せば、CSRF対策ができます。

コメントフォーム

著者情報

名前:スカーレット
2010年からWEBサイトやWEBアプリを作成しています。最初は趣味でブログを書いていましたがSEOを勉強するのが楽しくなり、そのままブロガーとして独立しました。その後、記事を書くだけでは物足りなくなり自分でWEBアプリの作成をスタート。現在はブロガー兼プログラマーとして活動しています。このWEBアプリ(ブロトーク)もDjangoで自作しました。ブロトークはブログとSNSを合体させたようなWEBアプリです。ブログを読んで気づいた事や感想などあれば、気軽にメッセージを送って頂ければと思います。WEB技術を一緒に勉強していけたらと思います。