Django-CSRF验证失败

2024-05-19 19:17:59 发布

您现在位置:Python中文网/ 问答频道 /正文

当我试图从教程中创建一个简单的表单时,收到一条CSRF验证失败的消息。我对CSRF验证实际上是什么做了一些研究,据我所知,为了使用它,你需要在html中使用CSRF_标记,但我没有

这是我的模板:

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

Tags: form表单messagedataifrequesthtmlcontact
3条回答

对于Django 1.4

设置.py

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

视图.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>

修复

1。在模板中的表单标记中包含{% csrf_token %}

2。如果出于任何原因在Django 1.3及更高版本上使用render_to_response,请将其替换为the ^{} 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 ^{} function was introduced in Django version 1.3-如果您使用的是古版本like 1.2 or below,则必须将render_to_response与aRequestContext一起使用:

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

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

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

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 attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request. 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. 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. If the victim is an administrative account, CSRF can compromise the entire web application. Source: The Open Web Application Security Project

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

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

它是可选的,但在默认情况下打开(默认情况下包括CSRF中间件)。您可以关闭它:

  • 通过使用csrf_excempt装饰器对特定视图进行装饰。
  • 对于每个视图,从settings.py的中间件列表中删除CSRF中间件

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

视图.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 %}

相关问题 更多 >