Nathan Crabbe
Nathan Crabbe

Reputation: 155

Django CSRF Cookie Not Setting

I have been trying to set up CSRF protection on my POST forms on my django 1.4.3 site and have been getting the 403 CSRF cookie not set error.

I believe I have followed the doc in detail, followed advice on many forums but all to no avail. I have stripped back the code as much as possible and the cookie just does not set. The csrfmiddlewaretoken is present, so that's not the source of the problem. I'm at my wit's end. No doubt the answer is stupidly simple, I just need a fresh set of eyes to point it out to me...

So here's some code:

#urls.py
...
url(r'^csrf/$', csrf_test, name='csrf_test'),
...

#views.py
...
from django.views.decorators.csrf import csrf_protect

@csrf_protect
def csrf_test(request):
    c = {}
    c.update(csrf(request))
    return render_to_response('csrf.html', c)
...

<!-- csrf.html -->
<html>
<body>
<form action="" method="post">
{% csrf_token %}
<input name="Submit" value="Submit" type="submit"/>
</form>
</body>
</html>

#settings.py
...
MIDDLEWARE_CLASSES = (                
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    #for db transactions. Check middleware order if faulty
    'django.middleware.transaction.TransactionMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'debug_toolbar.middleware.DebugToolbarMiddleware',
)
...
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
    'django.core.context_processors.csrf',
    'django.core.context_processors.request',
)
...

I am running the django development server on 127.0.0.1:8000.

I have cookies enabled on my browsers and have confirmed cookies are being set from other websites.

I have checked the csrfmiddlewaretoken is being passed as a POST variable.

I always get the error, this is not intermittent.

I have no problem with POST forms when I have disabled the middleware/used @csrf_exempt.

As I say, I'm at my wit's end. What on earth have I missed?

Thanks

Nathan

EDIT:

It now works, but I have no idea what has changed. For anyone reading this in the future I created a new project and app, it created the cookie straight away. Thinking it must have been a settings issue I changed the order of my MIDDLEWARE_CLASSES entries by moving 'django.middleware.csrf.CsrfViewMiddleware' down below 'django.contrib.sessions.middleware.SessionMiddleware'. I ran the original app and it worked. However to test whether the settings change was responsible I reversed the change. It still worked. Go figure.

I hope this helps someone in the future FWIW.

Nathan

Upvotes: 2

Views: 3453

Answers (2)

catherine
catherine

Reputation: 22808

def csrf_test(request):
    .....
    return render(request, 'csrf.html', { ..... })

Upvotes: 1

Aidan Ewen
Aidan Ewen

Reputation: 13328

if you're using render_to_response then you should probably use a RequestContext

This will handle the csrf protection for you -

def csrf_test(request):
    render_to_response('csrf.html', context_instance=RequestContext(request))

You don't need to include the csrf_protect decorator, since you've got the csrf middleware.

Upvotes: 1

Related Questions