LoginSignup
10

More than 3 years have passed since last update.

Django + axiosでCSRFエラーが発生する場合の対処方法

Last updated at Posted at 2019-11-10

1.解決したい問題

Django + axiosでPOST通信を行った時、

console.log
Forbidden (CSRF token missing or incorrect.): /top/telling
[10/Nov/2019 11:06:22] "POST /top/telling HTTP/1.1" 403 2556

のように、CSRF起因で403エラー(forbidden)で弾かれてしまう問題を解決します。

2.環境情報

・Django:2.2.6
・axios:0.19.0
・Vue.js:2.6.0

3.対処方法

CookieへCSRFトークンをセットする処理と、
axios利用時にCookieのどの情報をCSRFトークンとして使用するかの設定を行います。

1.CookieへCSRFトークンをセットする

htmlに {% csrf_token %} を記述し、CookieにCSRFトークンをセットします。

index.html(※一部抜粋)
<html xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="{% static 'css/uikit.min.css' %}"/>
    <link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
</head>
<body>
<div class="back">
    <div class="uk-animation-fade">
        <span class="uk-navbar-item title">Destiny - 運命の選択肢 -</span>
        <spanf class="uk-navbar-item sub-title">選択に迷ったらぜひご利用ください!幸運を祈ります!<br/></spanf>
        <div id="app">
            <form action="{% url 'top:index' %}" method="post">
                {% csrf_token %}
                <div class="uk-text-center">
                    <button id="btnStart" type="button" v-show="showStart" @click="onStart();"
                            class="uk-button uk-button-primary">占いを始める
                    </button>
(以降省略)

2.axios使用時にCookieのどの情報をCSRFトークンとして使用するかを設定する

下記2行をaxiosでのPOST通信時のロジックに追加します。

axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"

私の場合は下記のように実装しました。

main.js
var app = new Vue({
    el : '#app',
    data : {
        showStart: true,
        showSelect: false,
        showForm: false,
        showResult: false,
        choice: 2,
        formList: [],
        result: ""
    },
    methods : {
        onStart : function() {
           this.showStart = false;
           this.showSelect = true;
        },
        onSelect : function(){
           this.showSelect = false;
           for(var i = 0; i < this.choice; i++) {
             this.formList.push({id: i, form:""});
           }
           this.showForm = true;
        },
        onExecute : function(){
           this.showForm = false;
           this.showResult = true;
           axios.defaults.xsrfCookieName = 'csrftoken' // ←ココと
           axios.defaults.xsrfHeaderName = "X-CSRFTOKEN" // ←ココに追加しました
           axios.post('/top/telling',{
                formList: this.formList
            }).then(function(response) {
                this.result = response.data.result;
            }.bind(this)).catch(function(error) {
                console.log(error);
            })
        }
    }
});

私の場合は上記で解決しました。以上終わり。

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
10