django中的csrf错误

Posted

技术标签:

【中文标题】django中的csrf错误【英文标题】:csrf error in django 【发布时间】:2011-03-12 22:59:05 【问题描述】:

我想为我的网站实现登录。我基本上将 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,
    )

注册.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>

【问题讨论】:

【参考方案1】:

我遇到了完全相同的问题 - 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))

这为我解决了问题。

【讨论】:

对于当前的 django,更好的解决方案是使用 render() 而不是 render_to_response()。【参考方案2】:

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

'django.middleware.csrf.CsrfViewMiddleware',

为我工作......

【讨论】:

【参考方案3】:

稍后回答。

现在可以使用render 代替context_instance=RequestContext(request)

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

【讨论】:

【参考方案4】:

我正在使用 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',
)

【讨论】:

【参考方案5】:

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

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

【讨论】:

@stevejalim 讽刺的是,docs 建议它仍然适用于 1.2,但它已被弃用。【参考方案6】:

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

% csrf_token %

要了解原因,请查看CSRF docs

【讨论】:

这样做对我来说还不够;需要 user433033 解决方案【参考方案7】:

您需要将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,但原则是合理的。

【讨论】:

以上是关于django中的csrf错误的主要内容,如果未能解决你的问题,请参考以下文章

Django之CSRF

Django之CSRF

Django之CSRF

在 Django 中的 ajax POST 期间被禁止(CSRF 令牌丢失或不正确。)

禁止(CSRF 令牌丢失或不正确。)Django

Django中的CSRF