Search code examples
reactjsdjango-rest-frameworkdjango-csrf

Django, react & fetch - submitting CSRF token on post request


I am creating a webapp with Django (Rest) and templates that are spiced up by react components. These reactcomponents are connected toDjango_restframework API's.

The 'GET' requests are working just fine, but so far I've been unable to get the post requests to work. The problems seems to be centered arround:

{detail: "CSRF Failed: CSRF token missing or incorrect."}

These are the steps that I have taken:

1 - I've enabled CSRF_USE_SESSIONS = True in my settings.py

2 - I've added the CSRF tag in my django template, like so (I am using django webpack-loader, hence the other tag)

<div id="create_root"></div>
{% render_bundle 'main_create_assessment' 'js' %}
{% csrf_token %}

3 - I've added a function to fetch the CSRF from the cookie

function getCookie(name) {
    if (!document.cookie) {
      return null;
    }
    const token = document.cookie.split(';')
      .map(c => c.trim())
      .filter(c => c.startsWith(name + '='));

    if (token.length === 0) {
      return null;
    }
    return decodeURIComponent(token[0].split('=')[1]);
  }

  const csrftoken = getCookie('csrftoken')
  console.log(csrftoken)

(The 'console.log' statements show me that the 'csrftoken' variable is assigned the correct value, yet the post requests keeps failing on a 403 / missing/incorrect csrf token error. )

4 - I've added the csrf information to the header of the post request, like so:

  fetch(url, {
    credentials: 'include',
    method: 'POST',
    mode: 'same-origin',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-CSRFToken': csrftoken
    },
    body: JSON.stringify({
      title: this.state.title
    })
   })
  }

Again, my console.log statements seem to indicate that I am supplying the correct token, yet the 403 error keeps persisting. Could someone enlighten me on what I am doing wrong?


Solution

  • I managed to solve my problem!

    My sollution was correct, however I had to remove the CSRF_USE_SESSIONS = True from the settings.py

    And remove the {% csrf_token %} tag from the template.

    The POST requests work after these changes.