Sounds strange but what about the scenario posting contents with Javascript (for example AJAX) without using a form (could be possible to read several contents from the surface)
You must set a custom HTTP header, X-CSRFToken
, in your AJAX request. See: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
If you've already followed that advice, it should be working. Use something like Firebug to monitor the request that's being sent and inspect the headers to ensure that the custom header is truly being passed. If it's not, then check your implementation again to make sure you did it just as the docs describe.
Also note:
Due to a bug introduced in jQuery 1.5, the example above will not work correctly on that version. Make sure you are running at least jQuery 1.5.1.
There are two steps in configuring CSRF token, if you would want to post without a form. Basically get the csrftoken
from Cookie, and set the Header with csrftoken (before you POST the data).
1) Get the csrftoken
from Cookie.
// Function to GET csrftoken from Cookie
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
2) Once you have the csrftoken, you should set the Header with csrftoken (before you POST the data).
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
// Function to set Request Header with `CSRFTOKEN`
function setRequestHeader(){
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
}
function postSomeData() {
.....
setRequestHeader();
$.ajax({
dataType: 'json',
type: 'POST',
url: "/url-of-some-api/",
data: data,
success: function () {
alert('success');
},
error: function () {
alert('error');
}
});
}
One CSRF token is assigned to every session ( i.e. every time you log in). So before you wish to get some data entered by user and send that as ajax call to some function which is protected by csrf_protect decorator, try to find the functions that are being called before you are getting this data from user. E.g. some template must be being rendered on which your user is entering data. That template is being rendered by some function. In this function you can get csrf token as follows: csrf = request.COOKIES['csrftoken'] Now pass this csrf value in context dictionary against which template in question is being rendered. Now in that template write this line: Now in your javascript function, before making ajax request, write this: var csrf = $('#csrf').val() this will pick value of token passed to template and store it in variable csrf. Now while making ajax call, in your post data, pass this value as well : "csrfmiddlewaretoken": csrf
This will work even if you are not implementing django forms.
In fact, logic over here is : You need token which you can get from request. So you just need to figure out the function being called immediately after log in. Once you have this token, either make another ajax call to get it or pass it to some template which is accessible by your ajax.
it is simple with this code:
$.ajaxSetup({ data: {csrfmiddlewaretoken: '{{ csrf_token }}' },});
see more: https://stackoverflow.com/a/7715325/1743582