Django:如何覆盖CSRF_FAILURE_TEMPLATE

24
如果CSRF检查失败,Django会显示一个403错误页面。

Error page displayed on csrf error

这个错误似乎在常规使用中可能会发生,例如当用户在浏览器设置中禁用cookie使用时。
不幸的是,这个错误消息对最终用户来说并不是很有帮助,并且具有“django-error”布局(这是一个问题,因为例如网站导航缺失)。
Django有一个很好的机制来覆盖模板,但似乎这个模板是硬编码在代码中的。https://github.com/django/django/blob/1.6.8/django/views/csrf.py 有没有办法覆盖这个模板,以向用户提供更友好的消息?
3个回答

39

参考Django文档,您可以在settings.py中设置CSRF_FAILURE_VIEW,例如:

CSRF_FAILURE_VIEW = 'your_app_name.views.csrf_failure'

此外,您需要在视图中定义一个csrf_failure函数(需要符合这个签名:def csrf_failure(request, reason="")),该函数类似于:

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

您可以编写自定义模板如下:

<!DOCTYPE html>
<html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        {{ message }}
    </body>
</html>

谢谢。这正是我所需要的。只要注意,“reason”是开发者信息,不应该显示给最终用户。因此,在我的情况下,我不会在模板中显示它。 - luc
你会如何测试这个? - gdvalderrama
6
前往一个带有表单的页面,打开开发者工具(在Chrome中按下Ctrl+Shift+I),找到csrf输入字段,编辑其值,发送表单! - Jeb
@Jeb,厉害的hack,谢谢!我最终做的是在调试中设置一个URL来呈现该模板,这只是让我看到了csrf失败的模板,但不能确保它按照意图工作。 - gdvalderrama
@guival 在两个标签页中打开你的应用程序登录页面。先在一个标签页登录应用,然后尝试在另一个标签页登录。你应该会看到CSRF错误提示。 - Anoop Nair

14

4
403_csrf.html模板添加到项目的模板目录中。
如您在源代码django/views/csrf.py中所见:如果您有此模板,则将应用它。 无需配置任何内容。
您需要根据自己的需要自定义的模板内容:
<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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接