痛風とシステム障害を恐れるエンジニアのブログ

趣味のことだったり仕事に関することだったりを徒然なるままに。webとかオープン系の会社で働いてます。お仕事の依頼お待ちしておりまーす。

DjangoでAjaxをするときに詰まったこと

私は仕事ではPHPばかりですが、自社フレームワーク案件が多く、あまり有名なフレームワークの案件の経験がありません。
最近Laravelを触り始めたくらい(^^;
最近のフレームワークは標準でCSRF対応がされているので便利でございますなぁ。

Djangoも同様に普通にCSRF対応がされているようです。
今回はそこで少しつまずきました。

通常CSRF対策ではトークンをクライアントに発行してPOSTでリクエストが来た時にトークンの妥当性をチェックしている。らしい。
Laravelでは

{{ csrf_token() }}

関数をこんな感じでviewに埋め込んであげると、トークン用の項目を生成してくれるみたいです。


さて、今回の私の環境はDjangoを使っているとはいえViewの部分は殆どReact.jsで書いてます。
React.jsの中でダイアログを表示して、ダイアログ内のフォームをPOSTするような感じです。
さらにReact.jsをそのままJSで書いているのではなく、JSXで記述しているので、Djangoから直接JSXを触れそうにないという・・・。
もしかしたらできるかもしれないけど、今の私には無理(;´Д`)

色々調べてたらクッキーの保存するとか、ヘッダーにしのばせるとかあるみたい。

Cross Site Request Forgery protection | Django documentation | Django

あと、React.jsとは別のところでグローバル変数を宣言して利用する方法もあるみたいでした。
Djangoのviewで

<script type="text/javascript">
var CSRF_TOKEN = "{{ csrf_token }}";
</script>

グローバル変数で宣言しておいてJSXのほうでは

var ele = document.createElement('input');
ele.setAttribute('type', 'hidden');
ele.setAttribute('name', 'csrfmiddlewaretoken');
ele.setAttribute('value', CSRF_TOKEN);
form.appendChild(ele);

と記載してフォームに項目を追加してPOSTするようです。
私はとりあえずこっちでやってみました。
JSを見るとソースに丸見えだからもしかしたらCookieとかの方が良いのかもしれませんね。
まぁCookieも見ることできるから、あまり大差ないかもしれないけど(゚д゚)
CSRFのチェックを一部無効にするという方法もあるけど、それはできるだけ避けたいところですな( ゚Д゚)y─┛~~

参考にした記事stackoverflow.com