23

If csrf checking fails, Django display a page with 403 error.

Error page displayed on csrf error

It seems to me that this error can occur in regular use, for example, when the user disable cookie usage in his browser settings.

Unfortunately, this error message is not very helpful for the end-user and has a "django-error" layout (this is a problem because for example the site navigation is missing).

Django has a great mechanism for overriding templates but it seems that this template is hard-coded in the code. https://github.com/django/django/blob/1.6.8/django/views/csrf.py

Is there a way to override this template in order to provide a more friendly message to users?

luc
  • 41,928
  • 25
  • 127
  • 172

3 Answers3

37

Refer to the Django document, you can set CSRF_FAILURE_VIEW in your settings.py, such as:

CSRF_FAILURE_VIEW = 'your_app_name.views.csrf_failure'

Also, you'll need to define a csrf_failure function in your view (need to have this signature: def csrf_failure(request, reason="") based on the document), which is similar to :

def csrf_failure(request, reason=""):
    ctx = {'message': 'some custom messages'}
    return render_to_response(your_custom_template, ctx)

And you can write your custom template as:

<!DOCTYPE html>
<html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        {{ message }}
    </body>
</html>
dazedconfused
  • 1,312
  • 2
  • 19
  • 26
  • Thanks. It is exactly what I need. Just note that the "reason" is a developper message and should not be shown to the end user. So, in my case, I will not display it i my template. – luc Nov 14 '14 at 08:38
  • How would you test this? – gdvalderrama Jun 29 '16 at 15:53
  • 6
    @guival : Go to a page with a form, open developer tools (ctrl+maj+i on Chrome), find the csrf input field, edit its value, send the form ! – Jeb Mar 16 '17 at 16:09
  • @Jeb great hack, thanks! What I ended doing is setting a url to render that template in debug, that just allowed me to see the csrf failure template though, not make sure it was working as intentioned. – gdvalderrama Mar 16 '17 at 18:16
  • @guival Open your application login page in two tabs. Login to the app in one tab and then try to login on the other tab. You should see the CSRF error. – Anoop Nair Jun 16 '20 at 14:11
12

As of Django 1.10, you can simply add and customize the 403_csrf.html template: https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-CSRF_FAILURE_VIEW

Antoine Pinsard
  • 33,148
  • 8
  • 67
  • 87
Vic
  • 488
  • 6
  • 8
4

Add 403_csrf.html template to the project template directory.

As you can see in the source code django/views/csrf.py: if you have this template, it will be applied. Nothing needs to be configured.

Template content that you need to customize for your needs:

<div id="summary">
  <h1>{{ title }} <span>(403)</span></h1>
  <p>{{ main }}</p>
{% if no_referer %}
  <p>{{ no_referer1 }}</p>
  <p>{{ no_referer2 }}</p>
  <p>{{ no_referer3 }}</p>
{% endif %}
{% if no_cookie %}
  <p>{{ no_cookie1 }}</p>
  <p>{{ no_cookie2 }}</p>
{% endif %}
</div>
Andrei
  • 1,313
  • 4
  • 18
  • 35