Django CSRF with axios or jQuery

I found myself trying to create a JavaScript application which sends HTTP requests using axios against a Django backend that requires every POST/PUT/PATCH/DELETE request to have a valid CSRF token. Fortunately, axios allows to read the token from the Django cookie (thanks to @tobire42 for finding that out) and send it along with every request automatically, see this wonderful post about the different options on how to do that. I liked this solution to configure the client only:

import axios from 'axios';

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

This will pipe the csrftoken back through to Django, no more configuration needed. Please note: Django’s documentation about the default header name seems outdated and we need to use the one above instead (or configure the name to be whatever we like).

The same thing can be done with other frontend frameworks, e.g. for jQuery we can do (see Django docs for a getCookie() implementation):

$.ajaxSetup({
  beforeSend: function (xhr, settings) {
    xhr.setRequestHeader('X-CSRFToken', getCookie('csrftoken'));
  },
});
Advertisements

4 Comments

  1. This didn’t work for me but I have no idea why, the only difference from the axios side of things is that I use
    “`
    axios.defaults.withCredentials = true
    “`
    The error message I get from django is:
    “`
    Forbidden (CSRF token missing or incorrect.): /get_compound_data/
    [18/Sep/2017 15:24:37] “POST /get_compound_data/ HTTP/1.1” 403 2274
    “`

    Been stuck googling this for about absolutely ages at this point, any ideas would be greatly appreciated 🙂

    1. I don’t think the credentials setting is the problem, as far as I remember I am also using that. You should try to debug a) if the CSRF cookie is set in the browser correctly after authenticating, b) if that value is read correctly in the client and c) if it is correctly attached as a header to the outgoing request. You may want to add debug statements in the SessionAuthentication in your virtualenv’s Django package for that. Good luck!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s