12.17.2014

Cross-site request forgery (CSRF) issue when use POST form in django 1.7

Cross-site request forgery (CSRF)

I got a message when I tested to send POST form to server.

Forbidden (403)

CSRF verification failed. Request aborted.

Help

Reason given for failure:

    CSRF token missing or incorrect.
    
In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:

  • Your browser is accepting cookies.
  • The view function uses RequestContext for the template, instead of Context.
  • In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
  • If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.
You can customize this page using the CSRF_FAILURE_VIEW setting.


The reasons of CSRF verification fail are as follows.
https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/#rejected-requests 

By default, a ‘403 Forbidden’ response is sent to the user if an incoming request fails the checks performed by CsrfViewMiddleware. This should usually only be seen when there is a genuine Cross Site Request Forgery, or when, due to a programming error, the CSRF token has not been included with a POST form.

The error page, however, is not very friendly, so you may want to provide your own view for handling this condition. To do this, simply set the CSRF_FAILURE_VIEW setting.


Solution

https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/#how-to-use-it
  1. Add the middelware in your setting.py. (I already have added it.)

    MIDDLEWARE_CLASSES = (
     ...
        'django.middleware.csrf.CsrfViewMiddleware', #for csrf
    )

    Alternatively, you can use the decorator csrf_protect() on particular views you want to protect (see below).
  2. Use the csrf_token tag in your any template that uses a POST form.
       
       
  3. Use RequestContext() instead of Context()
    def write_form(request) :
        page_title = 'Upload your photo'
        tpl = loader.get_template('write.html')
        # use RequestContext for csrf
        ctx = RequestContext(request, {
                'page_title': page_title,
            })

        # ctx = Context({
        #     'page_title': page_title,
        # })
        return HttpResponse(tpl.render(ctx))
 Done


If you have a question how it works, read this.
https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/#how-it-works

1 comment:

rakeshrajput said...

Hi!! Very interesting information glad. I really liked your Information. Keep up the good work friend.
Finland VPS Hosting