Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ajax CSRF problem in Django 1.3

Tags:

ajax

django

csrf

According to django documentation, for ajax post request in 1.3 (at least with Jquery), we just need to add this snippet to main js file. This snippet get csrftoken from cookies, and then set up it for all ajax request. That's work, but what if csrftoken don't exist in cookies? I thought render_to_response and render both automatically checks if csrftoken in sessions, and set it for us, if token not there. But they are not. So, i need to implement it by myself? Or maybe there is another way to handle ajax csrf protection?

like image 756
nukl Avatar asked Mar 31 '11 12:03

nukl


2 Answers

When there is no form on a page that is already using {% csrf_token %}, the cookie will not be sent. Therefore, as you noted, you will get an error when you attempt to use Ajax on such a page. This will lead to erratic behavior if you have a site with a mix of pages with various combinations of forms and ajax posts.

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

The solution in the patch, will should roll out with 1.3.1, is the ensure_cookie_csrf decorator. That decorator does not exist in 1.3 or 1.2.5

No need to wait, however. Just add this line to any view which contains AJAX posts a CSRF form:

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 - this is exactly what that decorator does.

like image 62
Teilo Avatar answered Sep 27 '22 21:09

Teilo


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

The get_token function sets metainformation on the request object that in turn tells the django.middleware.csrf.CsrfViewMiddleware middleware to set the cookie.

like image 34
ojii Avatar answered Sep 27 '22 22:09

ojii