django中的csrf错误

时间:2010-07-07 17:32:43

标签: python django csrf django-csrf

我想实现我网站的登录。我基本上将Django Book中的以下位复制并粘贴在一起。但是,在提交我的注册表单时,我仍然收到错误(CSRF验证失败。请求中止。)。有人可以告诉我是什么引发了这个错误以及如何解决它?

这是我的代码:

views.py:

# Create your views here.
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response

def register(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            new_user = form.save()
            return HttpResponseRedirect("/books/")
    else:
        form = UserCreationForm()
    return render_to_response("registration/register.html", {
        'form': form,
    })

register.html:

<html>
<body>

{% block title %}Create an account{% endblock %}

{% block content %}
  <h1>Create an account</h1>

  <form action="" method="post">{% csrf_token %}
      {{ form.as_p }}
      <input type="submit" value="Create the account">
  </form>
{% endblock %}
</body>
</html>

7 个答案:

答案 0 :(得分:19)

我遇到了同样的问题 - 而Blue Peppers的回答让我走上正轨。在表单视图中添加RequestContext可以解决问题。

from django.template import RequestContext

def register(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
           new_user = form.save()
           return HttpResponseRedirect("/books/")
    else:
        form = UserCreationForm()
    c = {'form': form}
    return render_to_response("registration/register.html", c, context_instance=RequestContext(request))

这为我解决了。

答案 1 :(得分:8)

我正在使用 Django 1.2.3 ,我有一些间歇性的问题:

要做的事情:

确保模板中存在csrf令牌

<form action="" method="post">{% csrf_token %}

使用RequestContext

return render_to_response('search-results.html', {'results' : results}, context_instance=RequestContext(request) )

确保对GET使用RequestContext,如果它们由相同的视图函数处理,并呈现相同的模板。

即:

if request.method == 'GET':
    ...
    return render_to_response('search-results.html', {'results':results}, context_instance=RequestContext(request) )
elif request.method == 'POST':
    ...
    return render_to_response('search-results.html', {'results':results}, context_instance=RequestContext(request))

if request.method == 'GET':
    ...
    return render_to_response('search-results.html', {'results':results})
elif request.method == 'POST':
    ...
    return render_to_response('search-results.html', {'results':results}, context_instance=RequestContext(request))

确保'django.middleware.csrf.CsrfViewMiddleware'列在您的settings.py

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)

答案 2 :(得分:6)

假设您使用的是Django 1.2.x,只需在{{form.as_p}}之前添加:

{% csrf_token %}

要了解为何,请查看CSRF docs

答案 3 :(得分:2)

您需要在上下文中添加csrf(request)

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.core.context_processors import csrf

def register(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            new_user = form.save()
            return HttpResponseRedirect("/books/")
    else:
        form = UserCreationForm()
    con = {'form': form}
    con.update(csrf(request))
    return render_to_response("registration/register.html", con)

您可能需要将上下文转换为Context对象,而不是dict,但原则是合理的。

答案 4 :(得分:1)

如果您不想将{% csrf_token %}添加到每个表单,请将这2个中间件添加到设置文件中。

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

答案 5 :(得分:1)

稍后回答。

现在render可以使用而不是context_instance=RequestContext(request)

from django.shortcuts import render
return render(request, "registration/register.html", {
        'form': form,
    })

答案 6 :(得分:0)

如果您打算使用{%csrf_token%},请尝试从settings.py的MIDDLEWARE列表中删除以下行:

'django.middleware.csrf.CsrfViewMiddleware',

为我工作...