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'));
  },
});

7 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 comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.