DjangoとVue.jsにおいて、アプリを開発する際に、フロント側をVue.js、APIサーバーとしてDjangoを使用していた場合にどのようにして、CSRF対策を行うかといった部分でつまずいてしまっています。
ユーザーがURLからトップページなどにアクセスした場合に、表示されるファイルは、「Vueファイル」であるかと思います。
実際に表示されたファイルがForm画面であり、ユーザーが値を入力後、axiosによってDjango側にPOSTリクエストを行なった場合、CSRFトークンを投げなかった場合に、認証エラーとなってしまいます。
ここで疑問なのですが、Djangoのテンプレートを使用していた場合は、{ % csrf_token %}
とすることで、トークンが自動で付与されましたが、Vueファイルの場合はそのようなことが出来ません。
その為、どこかでDjangoからCSRFトークンをブラウザ側へ投げる、もしくはCSRFを突破する別の方法が必要であるかと思いますが、その方法が現状見つからない状況です。
Vue側はVueCliでプロジェクトを作成し、開発を進めている段階です。
以下は、axiosを用いてDjango側へリクエストを投げるVueファイルになります。
<template> <div> <h1>test-site</h1> <h5>test</h5> <p v-if="errors.length"> <b>Please correct the following error(s):</b> <ul> <li v-for="(error,index) in errors" :key="index">{{ error }}</li> </ul> </p> <form action="" method="get" v-on:submit.prevent="submit"> <input type="text" v-model="inputUrl" name="url" placeholder="http://example.com"> <button type="submit">送信</button> </form> </div> </template> <script> import axios from 'axios' import Cookies from 'js-cookie' export default { data() { return { errors:[], inputUrl:'', csrftoken:'', } }, methods: { submit(){ this.errors = []; this.csrftoken = Cookies.get('csrftoken'); console.log('csrftoken: ' , this.csrftoken); if(!this.inputUrl){ this.errors.push('URLを入力して下さい') }else if(!this.checkFormat(this.inputUrl)){ this.errors.push('URLが正しくありません') } if (!this.errors.length){ axios.post( '/polls/check/', this.inputUrl, { headers:{ 'X-CSRFToken':this.csrftoken } } ) .then(response => { console.log(response) }) .catch(error => { console.log(error) }) } }, checkFormat(url){ var re = /^http(|s)://.+/ return re.test(url); } }, } </script>
現状、Vue側では、this.csrftoken = Cookies.get('csrftoken');
にてクッキーの取得を行っていますが、当然Django側へアクセスをしていない為、CSRFトークンは存在せずundefined
となってしまっています。
CSRFトークンに関してはDjangoのドキュメントを読み、CSRFトークンを取得する方法は分かったのですが、送信する方法は分かりませんでした。
こちらの問題につきまして、解決策が見当たらない状況な為、ご助言頂けましたら幸いです。
回答2件
あなたの回答
tips
プレビュー