CSRF rejection (403) on trying to using Editor upload
CSRF rejection (403) on trying to using Editor upload

var editor;
var table;
function getCookie(name) {
var cookieValue = null;
console.log('document.cookie : '+document.cookie)
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
console.log('cookies : '+cookies);
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
console.log('cookie : '+cookie);
//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;
}
}
}
console.log('cookieValue : '+cookieValue)
return cookieValue;
}
// var csrftoken = Cookies.get('csrftoken');
var csrftoken = getCookie('csrftoken');
$(document).ready(function() {
editor = new $.fn.dataTable.Editor({
table: "#bill",
idSrc: 'pk',
i18n: {
create: {
button: "Создать",
title: "Создать новую запись",
submit: "Создать"
},
edit: {
button: "Изменить",
title: "Изменить эту запись",
submit: "Изменить"
},
remove: {
button: "Удалить",
title: "Удалить эту запись",
submit: "Удалить",
confirm: {
_: "Вы уверены что хотите удалить %d записей?",
1: "Вы уверены что хотите удалить эту запись?"
}
},
error: {
system: "Ошибка. Обратитесь к администратору."
}
},
ajax: {
create: {
type: 'POST',
url: '/api/bill/',
headers: {'X-CSRFToken': '{{ csrf_token }}'},
data: function(d) {
return JSON.stringify(d);
}
},
edit: {
type: 'PUT',
url: '/api/bill/_id_/',
headers: {'X-CSRFToken': '{{ csrf_token }}'},
data: function(d) {
return JSON.stringify(d);
}
},
remove: {
type: 'DELETE',
url: '/api/bill/_id_/',
headers: {'X-CSRFToken': '{{ csrf_token }}'}
},
data: function ( d ) {
console.log("'{{ csrf_token }}' ");
d.CSRFToken = '{{ csrf_token }}';
}
},
fields: [
....
{
label: "Скан-копия счёта:",
name: "scan",
type: "upload",
display: function ( id ) {
return '<img src="'+editor.file( 'images', id ).webPath+'"/>';
},
noImageText: 'Пока нет изображений.'
},
.....
{
label: "Примечания:",
name: "notes",
type: "textarea"
}]
});
My debug configuration: https://debug.datatables.net/ecohok
Error message: A server error occurred while uploading the file
CSRF token missing or incorrect.
I'm trying to upload files to my server, but I constantly get a ban on this and a 403 error. I've read a lot of topics on this forum and the main idea that I get was that the upload field either sends its own CSRF token or needs a new token that is different from the session token.
At the moment, I can say that the function returns an empty value, however, "{{csrf-token}}" really produces a unique value for each session.
Any requests to the server, with the exception of the request to download the file through the download, are performed correctly.
What confuses me is that the csrf token from "{{csrf token}}" and the token from the request cookie are different. Maybe I just did not understand how it works to the end.
This question has accepted answers - jump to:
Answers
The section of the manual should help, it's discussing that. There are also a few thread in the forum, such as here and here, that should get you going.
Colin
Ok, this is solve a problem with CSRF.
But it makes another. If i understand correctly, "upload" field in configuration above, makes it's own ajax POST request to server.
I have POST request for table with a dozen other fields + "upload", but not for single "upload" field.
I've tried this:
But it's still trying make a POST request, which is forbidden in this case.
I'm confusing. Why it should make it's own independent request? I need a make a separated serializer for processing it?
If you remove the
ajax
option from theupload
configuration object, it will use Editor's defaultajax
option.Allan
Thanks Allan.
I've already try this option, and it wasn;t a good solution for my case.
Still, i've found my own.
Using Django framework, it is simple add some extra action to your API. That's what i did:
Extra action 'image' for 'api/bill' is a excellent solver for asynchronous work with files.
It took some experiments with respond, but it works! In documentation says, that respond should be a JSON. When I turned a 'respond' to JSON string, upload gives me an error.
When i put a simple python dictionary, it started to work fine.
In my JS code it looks like this:
Couple words about this:
data: function(d) { d.DT_RowID = editor.ids(); },
Since "upload" field doen't support "id" expression, and put "pk" of my entry in url became a problem, i've used "editor.ids()" to get a value of "pk" from table. It saves in "DT_RowID" filed of request to server.
"id" expression would be a sipler and nicer, but this is also work.
I hope, it help someday someone.