【问题标题】:Django csrf token missing or incorrect errorDjango csrf 令牌丢失或不正确错误
【发布时间】:2014-09-10 16:01:26
【问题描述】:

我一直在使用 Django 开发一个网站,并试图根据我的应用程序中的一个模型来实现一个简单的表单。我在让它工作时遇到了一些问题,但我目前的主要问题是我不断收到以下错误:CSRF 令牌丢失或不正确。

我正在运行 Django 1.6 和 python 2.7。

我已经查看了以下帖子以尝试解决我的问题(以及我在适当情况下提供上下文参考的各种其他解决方案),但它对我不起作用:

Django: CSRF token missing or incorrect - 基本上,通过RequestContext 以及我的render_to_response 返回。

CSRF Token missing or incorrect - 我已确保django.middleware.csrf.CsrfViewMiddleware 出现在我的settings.py 文件中,并且我已尝试按照指示将django.core.context_processors.csrf 添加到我的TEMPLATE_CONTEXT_PROCESSORS 设置中,但没有任何变化。当我在 shell 中检查这些设置时,我得到以下输出:

> from django.conf import settings
> settings.TEMPLATE_CONTEXT_PROCESSORS
('django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug', 'django.core.context_processors.i18n',
'django.core.context_processors.media', 'django.core.context_processors.static',
'django.core.context_processors.tz',
'django.contrib.messages.context_processors.messages')

我将以下代码放在我的 settings.py 文件中,但我继续收到 403 CSRF 令牌错误:

import django.conf.global_settings as DEFAULT_SETTINGS

TEMPLATE_CONTEXT_PROCESSORS = DEFAULT_SETTINGS.TEMPLATE_CONTEXT_PROCESSORS + (
    'django.core.context_processors.csrf',
)

我也遵循了错误消息本身中给出的建议,即确保我有 {% csrf_token %} 标记,使用 RequestContext 而不是 Context。

来自我的 views.py 文件:

from django.shortcuts import render
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.template import loader, Context
from django.http import HttpResponse
from forms import StudentForm
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
from django.template import RequestContext

def edit(request):
form = StudentForm(request.POST or None)
if form.is_valid():
    form.save()
    return Redirect('/myprofile/')
return render(request, 'myprofile.html',{'form':form})

请注意,我已经阅读了其他几个解决此问题的指南,这些指南涉及以几种不同的方式包含 RequestContext:return render_to_response('myprofile.html', RequestContext(request, {}))return render_to_response('myprofile.html', RequestContext(request)),这些都不适合我。

我的 settings.py 文件:

import django.conf.global_settings as DEFAULT_SETTINGS

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myprofile',
)

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


TEMPLATE_CONTEXT_PROCESSORS = DEFAULT_SETTINGS.TEMPLATE_CONTEXT_PROCESSORS + (
    'django.core.context_processors.csrf',
)

我的html代码如下:

<form action = "/myprofile/" method = "post"> {% csrf_token %}
  <ul>
  {{ form.as_ul }}
  </ul>

  <input type = "submit" name = "Submit" value = "Edit Form">
</form>

请注意,我也尝试将令牌添加为隐藏输入,但这并没有解决我的问题。生成此视图的函数也与表单操作所引用的函数相同,&lt;form action = "/myprofile/" ...&gt;

我们将不胜感激任何有关此问题的帮助。

【问题讨论】:

    标签: django csrf django-csrf


    【解决方案1】:

    {{ csrf_token }} 似乎为空,并覆盖了由 {% csrf_token %} 生成的隐藏输入字段。只需从模板中删除带有 {{ csrf_token }} 的隐藏输入字段,它应该可以工作。

    此外,由于您使用的是 RequestContext,因此您不必手动将 CSRF 令牌添加到模板中,因此您可以从视图中删除以下代码。

    c = {}
    c.update(csrf(request))
    

    更多信息请参见https://docs.djangoproject.com/en/1.6/ref/contrib/csrf/#how-csrf-works

    【讨论】:

    • 感谢您的回复。我评论了哈立德的回答,只是因为他涵盖了同样的想法等等。您的链接确实为我提供了一些我错过的非常有用的附加信息,但还没有完全解决我的问题。
    【解决方案2】:

    你的问题在这里:

    return render_to_response('myprofile.html',{},RequestContext(request))
    

    虽然你已经添加了 csrf:

    c = {}
    c.update(csrf(request))
    

    您不会对 c 做任何事情。要一劳永逸地解决这个问题,只需使用render shortcut

    from django.shortcuts import render, redirect
    
    def edit(request):
         form = StudentForm(request.POST or None)
         if form.is_valid():
            form.save()
            return redirect('/myprofile/')
         return render(request, 'myprofile.html', {'form': form})
    

    接下来,在您的模板中,您只使用{% csrf_token %},而不是同时使用它和{{ csrf_token }}。该标签将呈现表单字段。

    【讨论】:

    • 感谢您的帮助。我已遵循您的建议,但仍然收到相同的错误。这让我相信这个问题可能是由我的代码的不同方面引起的,而不仅仅是文件中的原始代码。
    猜你喜欢
    • 2020-09-19
    • 2021-07-14
    • 2017-09-10
    • 2021-11-13
    • 2012-04-20
    • 2012-09-25
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    相关资源
    最近更新 更多