2

我一直在尝试在我的 django 1.4.3 站点上的 POST 表单上设置 CSRF 保护,并且一直收到 403 CSRF cookie not set 错误。

我相信我已经详细遵循了文档,在许多论坛上遵循了建议,但都无济于事。我已经尽可能地剥离了代码,cookie 只是没有设置。csrfmiddlewaretoken 存在,所以这不是问题的根源。我无计可施。毫无疑问,答案非常简单,我只需要一双新鲜的眼睛向我指出……

所以这里有一些代码:

#urls.py
...
url(r'^csrf/$', csrf_test, name='csrf_test'),
...

#views.py
...
from django.views.decorators.csrf import csrf_protect

@csrf_protect
def csrf_test(request):
    c = {}
    c.update(csrf(request))
    return render_to_response('csrf.html', c)
...

<!-- csrf.html -->
<html>
<body>
<form action="" method="post">
{% csrf_token %}
<input name="Submit" value="Submit" type="submit"/>
</form>
</body>
</html>

#settings.py
...
MIDDLEWARE_CLASSES = (                
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    #for db transactions. Check middleware order if faulty
    'django.middleware.transaction.TransactionMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'debug_toolbar.middleware.DebugToolbarMiddleware',
)
...
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
    'django.core.context_processors.csrf',
    'django.core.context_processors.request',
)
...

我在 127.0.0.1:8000 上运行 django 开发服务器。

我在我的浏览器上启用了 cookie,并确认正在从其他网站设置 cookie。

我检查了 csrfmiddlewaretoken 是否作为 POST 变量传递。

我总是收到错误,这不是间歇性的。

当我禁用中间件/使用 @csrf_exempt 时,我对 POST 表单没有任何问题。

正如我所说,我已无计可施。我到底错过了什么?

谢谢

弥敦道

编辑:

它现在有效,但我不知道发生了什么变化。对于将来阅读本文的任何人,我创建了一个新项目和应用程序,它立即创建了 cookie。认为这一定是一个设置问题,我通过将 'django.middleware.csrf.CsrfViewMiddleware' 移到 'django.contrib.sessions.middleware.SessionMiddleware' 下面来更改我的 MIDDLEWARE_CLASSES 条目的顺序。我运行了原始应用程序并且它工作正常。但是,为了测试设置更改是否负责,我撤消了更改。它仍然有效。去搞清楚。

我希望这对未来的 FWIW 有所帮助。

弥敦道

4

2 回答 2

1

如果您使用的是 render_to_response 那么您可能应该使用RequestContext

这将为您处理 csrf 保护 -

def csrf_test(request):
    render_to_response('csrf.html', context_instance=RequestContext(request))

你不需要包含csrf_protect装饰器,因为你有 csrf 中间件。

于 2013-02-13T07:47:39.530 回答
1
def csrf_test(request):
    .....
    return render(request, 'csrf.html', { ..... })
于 2013-02-13T10:38:24.740 回答