1

I'm trying to using AJAX POST with Django as per the docs - this works fine if I'm logged in to the site. But if I'm logged out or using incognito, my csrftoken is not being set - I've tried putting {{csrf_token}} to check, which returns the value NOTPROVIDED.

What could be causing the token not to generate?

  • I'm using render so I don't think it's a context processor issue
  • The django.middleware.csrf.CsrfViewMiddleware is present, and I've not changed any default csrf settings
  • The ensure_csrf_cookie decorator works fine

I'm running Django 1.7.

Simplified version of the view (without the ensure_csrf_cookie decorator):

def pg2(request, **kwargs):
    name_slug = kwargs.pop('name_slug')
    num_guests = request.session['guests']
    date = request.session['date']

    venue = get_object_or_404(Venue, name_slug=name_slug)
    try:
        rental = request.session['rental']
    except:
        rental = None

    filtered_items = Item.objects.filter(venue_id=venue.pk)

    context = {'venue':venue, 'rental':rental, 'filtered_items':filtered_items}
    return render(request, 'app/pg2.html', context)

My middleware in settings:

MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.common.BrokenLinkEmailsMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.contrib.redirects.middleware.RedirectFallbackMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'project.middleware.SecureRequiredMiddleware', # to add SSL
)
Community
  • 1
  • 1
wasabigeek
  • 2,923
  • 1
  • 21
  • 30
  • You can read about using [ajax in the Django docs](https://docs.djangoproject.com/en/1.9/ref/csrf/#ajax) as well; if you are using jQuery, [here is a wrapper](https://github.com/thornomad/django-hitcount/blob/master/hitcount/static/hitcount/jquery.postcsrf.js) that does the business for you. – thornomad Dec 28 '15 at 22:06
  • Thanks @thornomad, as mentioned I was following the code in the docs. What's not working is the csrftoken is not even being generated in the first place - have updated the question. – wasabigeek Dec 29 '15 at 15:22
  • Maybe post your code then, `views.py` in particular. What version of Django? – thornomad Dec 30 '15 at 02:40

1 Answers1

0

Youn need to explicitly send the cookie in all Ajax POSTs. To get the cookie in the first place, you can run the following in your JS file:

var c = getCookie('csrftoken');

But to make the above getCookie function work, create a new javascript file with the code as given and call it in your html template. Hope it works for you!

ajaxpostcsrf.js

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]);
        if (cookie.substring(0, name.length + 1) == (name + '=')) {
            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
            break;
        }
    }
}
return cookieValue;
}
$.ajaxSetup({
    headers: { "X-CSRFToken": getCookie("csrftoken") }
});
Utkarsh Sinha
  • 941
  • 2
  • 11
  • 30
  • Thanks @Utkarsh - as mentioned though, I did try this as per the docs. What's not working is the csrftoken is not even being generated in the first place. Have updated the question. – wasabigeek Dec 29 '15 at 15:21