Django, Axios and CSRF

I am currently building a simple Django based web-app. Part of this app is a registration form. It has a rather nice UI, built from Vue, and I’m POSTing the data back to Django using Axios.

One great thing about Django is it’s built-in CSRF protection. While I’m not an expert and can’t say it’s the best CSRF protection, at the very least it’s nice that it has something built in.

When posting via Axios though, you need to send through the CSRF token, somehow. Everyone was saying you had to post it back, but it took me a while to figure out where you should be placing it. Eventually I found this snippet from the official Django Docs.

The CSRF header name is HTTP_X_CSRFTOKEN by default, but you can customize it using the CSRF_HEADER_NAME setting.

This answered my questions, and I ended up with this little bit of JS inside my Vue method.

submit: function() {
    data: {...}; // The exact data doesn't matter
    csrftoken = Cookies.get('csrftoken'); // Using JS Cookies library
    headers = {X_CSRFTOKEN: csrftoken};
    axios.post(url,data,{headers: headers});
}

Now of course I had a .then and .catch section after axios’ .post, but that should at least give you some idea of how you can do it.

Update:

After reviewing this and how Django works, I’ve made a quick change to this document. Django adds “HTTP_” to all header names, and converts all dashes to underscores. So if your client sends a 'X-XSRF-TOKEN' header, the setting should be 'HTTP_X_XSRF_TOKEN'. In order to make use of the default setting, you need to send through X_CSRFTOKEN or X-CSRFTOKEN as the header name. If you use X-CSRFTOKEN you need to wrap it in ‘ in the JS code. IE:

headers = {'X-CSRFTOKEN': csrftoken};

Now you can avoid traps that I fell into.

Leave a Reply

Your email address will not be published. Required fields are marked *