Search code examples
javascriptdjangoaxioscsrf-token

"Forbidden (CSRF token missing or incorrect.):" using Django and JS


I'm doing a POST request using Axios in my JS code to send some information to my locally hosted Django server. I have {% csrf_token %} in my html code form but don't know how to send the csrf token using Axios.

I get this error in the terminal: "Forbidden (CSRF token missing or incorrect.): /api/scoring/submit_score_details".

How do I correctly insert the csrf token in my axios post? Right now, I don't think JS can read {{ csrf_token }} as I have it. I've been searching Stack but it seems most people are using jQuery or some other type of JS.

To save space I didn't post what the variables in the payload are but they're all just strings.

I can get the error to go away if I put @csrf_exempt above the my function in the views.py file.

{
let payload = {
    "csrfmiddlewaretoken": "{{ csrf_token }}",
    "math_problem": problem,
    "user_answer": userInput,
    "true_answer": correctAnswer,
    "question_status": questionStatus,
}
console.log(payload);
axios.post('../api/scoring/submit_score_details', payload)
}
<div class="col text-center">
    <button id="start" type="button" class="btn btn-primary btn-lg">
        New Problem
    </button>
    <p id="math_problem"></p>
    <form id="inputForm" method="POST">
        {% csrf_token %}
        <input id="user_input" autocomplete="off" class="form-control form-control-lg" type="text" placeholder="Type your answer here">
        <input id="correct_answer" type="hidden">
    </form>
    <br>
    <button id="result_check" type="button" class="btn btn-primary btn-lg">Check</button>
    <script src={% static 'js/game_logic.js' %}></script>
</div>

{
let payload = {
    "csrfmiddlewaretoken": "{{ csrf_token }}",
    "math_problem": problem,
    "user_answer": userInput,
    "true_answer": correctAnswer,
    "question_status": questionStatus,
}
console.log(payload);
axios.post('../api/scoring/submit_score_details', payload)
}
<form id="inputForm" method="POST">
    {% csrf_token %}
    <input id="user_input" autocomplete="off" class="form-control form-control-lg" type="text" placeholder="Type your answer here">
    <input id="correct_answer" type="hidden">
</form>


Solution

  • So I ended up doing some googling and asking a friend. We came up with a solution.

    We had to add two lines of code to make things work:

    axios.defaults.xsrfCookieName = 'csrftoken';
    axios.defaults.xsrfHeaderName = 'X-CSRFToken';
    

    We also got rid of the 'payload' variable and just put everything in the Axios code.

    {
            axios.defaults.xsrfCookieName = 'csrftoken';
            axios.defaults.xsrfHeaderName = 'X-CSRFToken';
            axios.post('../api/scoring/submit_score_details', {
                "math_problem": problem,
                "user_answer": userInput,
                "true_answer": correctAnswer,
                "question_status": questionStatus,
            });
            console.log(`Problem:${problem},
                         User Input: ${userInput},
                         Correct Answer: ${correctAnswer},
                         Question Status: ${questionStatus}`
                         );
        };
    <div class="col text-center">
        <button id="new_problem_button" type="button" class="btn btn-primary btn-lg">
            New Problem
        </button>
        <p id="math_problem"></p>
        <form id="inputForm" method="POST">
            {% csrf_token %}
            <input id="user_input" autocomplete="off" class="form-control form-control-lg" type="text" placeholder="Type your answer here">
            <input id="correct_answer" type="hidden">
        </form>
        <br>
        <button id="result_check" type="button" class="btn btn-primary btn-lg">Check</button>
        <script src={% static 'js/game_logic.js' %}></script>
    </div>

    Here's a link that helped us.