【问题标题】:Django - CSRF verification failedDjango - CSRF 验证失败
【发布时间】:2010-12-28 16:43:02
【问题描述】:

我在尝试根据教程制作简单表单时收到 CSRF 验证失败消息。我对 CSRF 验证实际上是什么做了一些研究,据我所知,为了使用它,您需要在 html 中使用这些 csrf_token 标记之一,但我没有那个

这是我的模板:

<form action="/testapp1/contact/" method="post">
    {{ form.as_p }}
    <input type="submit" value="Submit" />
</form>

相当简单,位于contact.html

这是我的 urlconf: 从 django.conf.urls.defaults 导入 *

urlpatterns=patterns('testapp1.views',
    (r'^$', 'index'),
    (r'^contact/$','contact')
)

应用名称为 testapp1。当我输入我的 url (http://localhost:8000/testapp1/contact) 时,我正确地转到了表单。然后当我提交表单时,我收到验证错误。

以下是我的观点,虽然我认为这无关紧要:

def contact(request):
    if request.method == 'POST': # If the form has been submitted...
        form = ContactForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            subject = form.cleaned_data['subject']
            message = form.cleaned_data['message']
            sender = form.cleaned_data['sender']
            cc_myself = form.cleaned_data['cc_myself']
            recipients = ['info@example.com']
            if cc_myself:
                recipients.append(sender)
            print 'Sending Mail:'+subject+','+message+','+sender+','+recipients
            return HttpResponseRedirect('/thanks/') # Redirect after POST
    else:
        form = ContactForm() # An unbound form

    return render_to_response('contact.html', {
        'form': form,
    })

【问题讨论】:

    标签: python django


    【解决方案1】:

    修复

    1。在模板中包含{% csrf_token %}inside表单标签。

    2。如果出于任何原因您在 Django 1.3 及更高版本上使用render_to_response,请将其替换为the render function。替换这个:

    # Don't use this on Django 1.3 and above
    return render_to_response('contact.html', {'form': form})
    

    有了这个:

    return render(request, 'contact.html', {form: form})
    

    The render function was introduced in Django version 1.3 - 如果您使用的是旧版本 like 1.2 or below,您必须使用 render_to_responseRequestContext

    # Deprecated since version 2.0
    return render_to_response('contact.html', {'form': form},
                       context_instance=RequestContext(request))
    

    什么是 CSRF 保护,我为什么需要它?

    这是一种攻击,敌人可以强迫你的用户做一些令人讨厌的事情,比如转移资金、更改他们的电子邮件地址等等:

    Cross-Site Request Forgery (CSRF) 是一种攻击,它会强制最终用户在当前已通过身份验证的 Web 应用程序上执行不需要的操作。 CSRF 攻击专门针对改变状态的请求,而不是窃取数据,因为攻击者无法看到对伪造请求的响应。借助一些社会工程学的帮助(例如通过电子邮件或聊天发送链接),攻击者可能会诱骗 Web 应用程序的用户执行攻击者选择的操作。如果受害者是普通用户,成功的 CSRF 攻击会迫使用户执行状态更改请求,例如转移资金、更改电子邮件地址等。如果受害者是管理帐户,CSRF 可能会破坏整个 Web 应用程序。来源:The Open Web Application Security Project

    即使您现在不关心这种事情,应用程序也可能会增长,因此最佳做法是保持 CSRF 保护。

    CSRF 保护不应该是可选的吗?

    它是可选的,但默认打开(默认包含 CSRF 中间件)。您可以将其关闭:

    • 使用csrf_exempt 装饰器装饰特定视图。
    • 通过从settings.py 的中间件列表中删除 CSRF 中间件来为每个视图

    如果您在系统范围内关闭它,您可以通过使用 csrf_protect 装饰器装饰特定视图来打开它。

    【讨论】:

    • 是的,我刚刚开始使用它。我想我认为 CSRF 保护是可选的。显然,如果您提交一个表格,您需要使用 CSRF,否则它将无法工作。那好吧。谢谢
    • @JPC:这取决于您的配置。如果您使用 CSRF 中间件,则除非您使用 csrf_excempt 装饰器,否则它是必需的。如果您不使用它,则不需要它,除非您使用 csrf_protect 装饰器。
    • 您还需要import from django.template import RequestContext
    【解决方案2】:

    views.py:

    from django.shortcuts import render_to_response
    from django.template import RequestContext
    
    def my_view(request):
        return render_to_response('mytemplate.html', context_instance=RequestContext(request)) 
    

    mytemlate.html:

    <form action="/someurls/" method="POST">{% csrf_token %}
    

    【讨论】:

      【解决方案3】:

      对于 Django 1.4

      settings.py

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

      view.py

      from django.template.defaulttags import csrf_token
      from django.shortcuts import render
      
      @csrf_token
      def home(request):
          """home page"""
          return render(request,
              'template.html',
                  {}
          )
      

      模板.html

      <form action="">
          {% csrf_token %}
      ....
      </form>
      

      【讨论】:

        猜你喜欢
        • 2012-09-08
        • 2015-06-02
        • 2017-03-29
        • 2011-06-14
        • 2020-03-24
        • 2014-05-23
        相关资源
        最近更新 更多