Skip to content

Instantly share code, notes, and snippets.

@richtier

richtier/ajax and CSRF

Last active Dec 25, 2015
Embed
What would you like to do?
I was asked "I am running into the 403 forbidden issue with django and ajax and was wondering if you could help me a little."
(note, the concept definitely works, but the implementation may have some bug, spelling mistakes etc).
Your problem is your request is missing the Cross Site Request Forgery token (CSRF).
This is a precaution django provide automatically to prevent others doing nefarious stuff.
Non-POST requests don't need the CSRF token, but for POST we need to do some magic:
we need to pass the CSRF token from django to javascript. This is best done like so:
In django:
from django.middleware.csrf import get_token
csrf_token = get_token(self.request) # this is the CSRF token. pass it to your base template.
In your base tample:
/* see this as a html "dictionary" that is middleground between django and js, remember its a bad practice to put js in html file */
<div id="django-data" data-CSRF="{{csrf_token}}"/>
In javascript:
var csrf_token = $("#django-data").data().CSRF;
// note POST method does not cache
$.ajaxSetup({timeout: 2000, }); // docs -- api.jquery.com/jQuery.ajaxSetup/
// send the request
$.post(url, {}, 'json') //docs -- api.jquery.com/jQuery.post/
.done(function(data){
// do stuff on success
})
.fail(function(){
//do stuff on fail
})
.always(function(){
// do stuff after either dail or success
})
// this automatically intercepts each ajax request, checks if it is going to
// your server, and adds the csrf token if so:
$(document).ajaxSend(function(event, xhr, settings) {
function sameOrigin(url) {
var host = document.location.host,
protocol = document.location.protocol,
sr_origin = '//' + host,
origin = protocol + sr_origin;
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
!(/^(\/\/|http:|https:).*/.test(url));
}
function safeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", csrf_token);
}
});
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment