Django CSRF protection and AJAX calls

67 views
Skip to first unread message

Kevin

unread,
May 26, 2020, 2:19:08 PM5/26/20
to Django users
Hi,

I'm not able to POST to django without having a csrf_token cookie sent with the request, though the documentation says you can set an X-CSRFToken header - it appears to be entirely ignored.

The behaviour has been pointed out a couple of times before:



but it doesn't appear to have ever been triaged by a project member or looked into in any way.

I'm trying to find a definitive answer - should a POST request to a CSRF protected endpoint work without the cookie if the header is set?

Thanks

-Kevin

Allan Rafael

unread,
Jun 9, 2020, 10:23:46 PM6/9/20
to django...@googlegroups.com
Você pode criar um arquivo js chamado ajax_post_config.js e nele inserir o seguinte código:


function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
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 = cookies[i].trim();
// 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;
}
let csrftoken = getCookie('csrftoken');

E no template html, você deve inserir beforeSend assim:

<script src="{% static 'path.../ajax_post_config.js' %}"></script>
<script>
$.ajax({
url: url,
type: 'POST',
data: {'data1': data1},
dataType: 'json',
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
},
...
</script>

É isso, espero ter ajudado



Atenciosamente,

Allan Rafael Ferreira de Oliveira
Bacharel em Ciência da Computação  Universidade Estadual da Paraíba
Estagiário de TI
 • 
PrestContas


--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/1e318fcd-32bc-448b-bd4d-05b92f4a8afc%40googlegroups.com.

Boris Pérez

unread,
Jun 10, 2020, 11:57:52 AM6/10/20
to Django users
My way, i use the csrf_token tag on template, an pass it to the view in the ajax call, using
$.ajax({
url : url,
type : "POST", // http method
data : {'csrfmiddlewaretoken': $('input[name="csrfmiddlewaretoken"]').val(),
'v1':v1,'v2':v2,....
}, // data sent with the post request

Kevin

unread,
Jun 10, 2020, 11:48:13 PM6/10/20
to Django users
Thanks Boris & Allan,

I was able to research the problem further and found that my header was being set entirely correctly, and the Django csrf middleware does in fact require both the cookie AND the header to be set. It's not an either/or, and there is an explicit error message for when either of them are missing and csrf secured method is used. The POSTs that I am seeing fail appear to be because the csrf cookie is missing sometimes. I'm not sure as of yet if this is because Django is not creating it, or because certain browsers (notably Safari) are not sending it, or a mix of both.
Reply all
Reply to author
Forward
0 new messages