AJAX CSRF issue in Django 1.3

According to the django documentation, to request an ajax post in 1.3 (at least with jQuery) we just need to add this fragment to the main js file. This snippet gets csrftoken from cookies and then configures it for all ajax requests. This work, but what if csrftoken does not exist in cookies? I thought that render_to_response and rendering will automatically check if csrftoken will be in the sessions, and set it for us if the token does not exist. But this is not so. So, do I need to implement it myself? Or maybe there is another way to handle ajax csrf protection?

+6
ajax django csrf
source share
5 answers

If a page that already uses {% csrf_token%} does not have a form, a cookie will not be sent. Therefore, as you noted, you will receive an error message when you try to use Ajax on such a page. This will lead to erratic behavior if you have a website with a combination of pages with various combinations of forms and ajax posts.

This has been reported and fixed: https://code.djangoproject.com/ticket/15354

The solution in the patch, to be deployed with 1.3.1, is the decor_cookie_csrf decorator. This decorator does not exist in 1.3 or 1.2.5

No need to wait, however. Just add this line to any view containing AJAX, a CSRF form message:

request.META["CSRF_COOKIE_USED"] = True 

Example:

 def calculator(request): request.META["CSRF_COOKIE_USED"] = True return render_to_response('calc.html', {'form': CalcForm()}) 

FYI is exactly what this decorator does.

+11
source share

Your cookie will only have the CSRF token if the template tag {% csrf_token %} was used in the template for the shadow request, or if you call get_token (with the request object as an argument) from django.middleware.csrf .

The get_token function sets the meta information on the request object, which in turn tells django.middleware.csrf.CsrfViewMiddleware software to set a cookie.

+3
source share

As for Ajax, you have to pass the csrf token with every request. For jQuery, I use the following code:

 $.ajaxPrefilter(function(options, originalOptions, jqXHR) { if(!options.crossDomain) { if(options.data) { options.data += "&"; } else { options.data = ""; } options.data += "csrfmiddlewaretoken={{csrf_token}}"; } }); 
+3
source share

One way I found to get around this is to use an existing form as a starting point for your AJAX data.

 <form id="ajax_form" stye="display: none;">{% csrf_token %}</form> 

Then you can use this in your JavaScript through the jQuery Serialize function:

 var data = $('#ajax_form').serialize(); data += "&mydata=69"; 

You can even use hidden fields in this hidden form, so you don't need to use string concatenation to create your POST data.

+1
source share

If you use the @csrf_protect decorator, make sure that both the view with the form and the view that the data is sent to use the decorator.

I had a similar problem. I only have @csrf_protect in the message view, which worked fine-tuning locally, but when I went on air o received 403 verification failed, adding the decorator that he looked at the page, this

+1
source share

All Articles