1

I have the following JS code in my django template:

fetch("http://127.0.0.1:8000/api/endpoint", {
      method: "POST",
      body: $("#form").serializeArray(),
    }).then(function(data) {
    });

In the api/endpoint, I just get:

Forbidden (CSRF token missing or incorrect.): /api/endpoint

How do I add the csrf token in the fetch?

3 Answers3

3

I was having issues with this for hours on a similar project. I finally found the solution! I hope this information helps. The script I'm using is not on the django template, so using csrfmiddlewaretoken: '{{ csrf_token }}' wouldn't work for me.

I added in the "credentials": 'same-origin' as listed above, but also included "X-CSRFToken": getCookie("csrftoken"), which uses the function included at the bottom. It was this second bit that I needed. So your code should look something like:

fetch("http://127.0.0.1:8000/api/endpoint", {
  method: "POST",
  body: $("#form").serializeArray(),
  credentials: 'same-origin',
  headers: {
      "X-CSRFToken": getCookie("csrftoken")
  }
})
.then(function(data) {
})
.catch(err => console.log(err));

Then you need this function added:

function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
    var cookies = document.cookie.split(';');
    for (var i = 0; i < cookies.length; i++) {
        var cookie = jQuery.trim(cookies[i]);
        // Does this cookie string begin with the name we want?
        if (cookie.substring(0, name.length + 1) === (name + '=')) {
            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
            break;
        }
    }
}
return cookieValue;}

And of course the method has to be on the same page. Taken from Django Docs. https://docs.djangoproject.com/en/1.11/ref/csrf/#ajax

I found this information from this post: https://stackoverflow.com/a/43943556 from user Ska

J2hero
  • 46
  • 3
1

Inside your body, you can pass the csrf token inside your ajax request like this:

body : {
   // Other stuff
   csrfmiddlewaretoken: '{{ csrf_token }}'
}

This should solve your problem.

Edit : Fetch doesn't include Cookies by default inside its request. To do so you need to add this line inside your fetch request as on option:

credentials : 'include' // For Cors
credentials : 'same-origin' // For same origin requests 
spaceSentinel
  • 630
  • 6
  • 9
1

In my case I was using plain Javascript and Django.

I had to hide a {% csrf_token %} in my HTML layout so that I could access it in my fetch request as follows:

HTML template:

<head> 
  <title>Page title</title>
  {% csrf_token %}
</head>

index.js:

csrf_token = document.getElementsByName('csrfmiddlewaretoken')[0].value

fetch(`${url}`, {
        method : 'put',
        body : JSON.stringify(your_dat),
        headers: { "X-CSRFToken": csrftoken },
        credentials : 'same-origin',
    })

it may not be the most beatiful code

Nestigd
  • 11
  • 2