简体   繁体   English

Django - CSRF验证失败

[英]Django - CSRF verification failed

I'm getting a CSRF verification failed message when trying to make a simple form from a tutorial. 尝试从教程中创建一个简单的表单时,我收到CSRF验证失败消息。 I did a little research into what CSRF verification actually is, and to my knowledge, in order to use it you need one of those csrf_token tags in your html, but I don't have that 我对CSRF验证实际上做了一些研究,据我所知,为了使用它你需要在你的html中使用其中一个csrf_token标签,但我没有

Here's my template: 这是我的模板:

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

Fairly straightforward, located at contact.html 相当简单,位于contact.html

Here's my urlconf: from django.conf.urls.defaults import * 这是我的urlconf:来自django.conf.urls.defaults import *

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

The app name is testapp1. 应用名称为testapp1。 When I type my url (http://localhost:8000/testapp1/contact), I correctly go to the form. 当我输入我的网址(http:// localhost:8000 / testapp1 / contact)时,我正确地转到表单。 Then when I submit the form, I get the verification error. 然后,当我提交表单时,我收到验证错误。

Here's my view although I don't think it's relevant: 这是我的观点,虽然我不认为它是相关的:

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,
    })

The fix 修复

1 . 1 include {% csrf_token %} inside the form tag in the template. 在模板中的表单标记包含{% csrf_token %}

2 . 2 if for any reason you are using render_to_response on Django 1.3 and above replace it with the render function . 如果由于任何原因你在Django 1.3及更高版本上使用render_to_response ,则用render函数替换它。 Replace this: 替换这个:

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

With this: 有了这个:

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

The render function was introduced in Django version 1.3 - if you are using an ancient version like 1.2 or below you must use render_to_response with aa RequestContext : render函数是在Django 1.3版本中引入的 - 如果您使用的是1.2或更低版本的古老版本,则必须使用带有RequestContext render_to_response

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

What is CSRF protection and why would I want it? 什么是CSRF保护,为什么我需要它?

It is an attack where an enemy can force your users to do nasty things like transferring funds, changing their email address, and so forth: 这是一种攻击,敌人可以强迫你的用户做一些令人讨厌的事情,如转移资金,更改他们的电子邮件地址等等:

Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated. 跨站点请求伪造(CSRF)是一种攻击,它强制最终用户在当前对其进行身份验证的Web应用程序上执行不需要的操作。 CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request. CSRF攻击专门针对状态更改请求,而不是数据被盗,因为攻击者无法查看对伪造请求的响应。 With a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker's choosing. 通过社交工程的一些帮助(例如通过电子邮件或聊天发送链接),攻击者可以欺骗Web应用程序的用户执行攻击者选择的操作。 If the victim is a normal user, a successful CSRF attack can force the user to perform state changing requests like transferring funds, changing their email address, and so forth. 如果受害者是普通用户,则成功的CSRF攻击可以强制用户执行状态更改请求,例如转移资金,更改其电子邮件地址等。 If the victim is an administrative account, CSRF can compromise the entire web application. 如果受害者是管理帐户,CSRF可能会危及整个Web应用程序。 Source: The Open Web Application Security Project 来源: 开放Web应用程序安全项目

Even if you don't care about this kind of thing now the application may grow so the best practice is to keep CSRF protection on. 即使您现在不关心这类事情,应用程序也可能会增长,因此最佳做法是保持CSRF保护。

Should not CSRF protection be optional? CSRF保护不应该是可选的吗?

It is optional but turned on by default (the CSRF middleware is included by default). 它是可选的,但默认情况下处于打开状态(默认情况下包含CSRF中间件)。 You can turn it off: 你可以把它关掉:

  • for a particular view by decorating it with the csrf_excempt decorator. 通过使用csrf_excempt装饰器进行装饰来获取特定视图。
  • for every view by removing the CSRF middleware from the middleware list at settings.py 通过在settings.py从中间件列表中删除CSRF中间件来获取每个视图

If you turn it off system-wide you can turn it on for a particular view by decorating it with the csrf_protect decorator. 如果您在系统范围内关闭它,可以通过使用csrf_protect装饰器进行装饰来为特定视图打开它。

views.py: 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: mytemlate.html:

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

For Django 1.4 对于Django 1.4

settings.py settings.py

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

view.py 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',
            {}
    )

template.html template.html

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM