CSRF 令牌缺失或不正确
Django 的初学者,我已经尝试解决这个问题很长时间了。 我的中间件类中确实有“django.middleware.csrf.CsrfViewMiddleware”,并且我的帖子表单中确实有令牌。
这是我的代码,我做错了什么?
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from chartsey.authentication.forms import RegistrationForm
from django.template import RequestContext
from django.core.context_processors import csrf
def register(request):
if request.method == 'POST':
c = RequestContext(request.POST, {})
form = RegistrationForm(c)
if form.is_valid():
new_user = form.save()
return HttpResponseRedirect("/")
else:
form = RegistrationForm()
return render_to_response("register.html", {'form': form, }, )
这是我的模板:
{% block content %}
<h1>Register</h1>
<form action="" method="POST"> {% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
{% endblock %}
Beginner at Django here, I've been trying to fix this for a long time now.
I do have 'django.middleware.csrf.CsrfViewMiddleware' in my middleware classes and I do have the token in my post form.
Heres my code, what am I doing wrong?
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from chartsey.authentication.forms import RegistrationForm
from django.template import RequestContext
from django.core.context_processors import csrf
def register(request):
if request.method == 'POST':
c = RequestContext(request.POST, {})
form = RegistrationForm(c)
if form.is_valid():
new_user = form.save()
return HttpResponseRedirect("/")
else:
form = RegistrationForm()
return render_to_response("register.html", {'form': form, }, )
Here's my Template:
{% block content %}
<h1>Register</h1>
<form action="" method="POST"> {% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
{% endblock %}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
更新:这个答案来自 2011 年。CSRF 如今很简单。
这些天你应该使用
render
快捷函数return render(request, 'template.html')
它会自动使用RequestContext
因此下面的建议已经过时8年了。render
https://docs.djangoproject.com /en/2.2/topics/http/shortcuts/{% csrf_token %}
模板标记原始响应
它没有呈现任何内容(或者您的意思是您在实际的 HTML 中确认正在生成 CSRF 令牌?)
中提交 我的猜测是您在模板中有该标记,但
RequestContext
而不是字典或者确保您的
CONTEXT_PROCESSORS
设置中有django.core.context_processors.csrf
。https://docs.djangoproject.com/en/dev/ref/contrib/ csrf/
或者将令牌添加到您的上下文中手动
Update: This answer is from 2011. CSRF is easy today.
These days you should be using the
render
shortcut functionreturn render(request, 'template.html')
which usesRequestContext
automatically so the advice below is outdated by 8 years.render
https://docs.djangoproject.com/en/2.2/topics/http/shortcuts/{% csrf_token %}
template tagOriginal Response
My guess is that you have the tag in the template but it's not rendering anything (or did you mean you confirmed in the actual HTML that a CSRF token is being generated?)
Either use
RequestContext
instead of a dictionaryOr make sure you have
django.core.context_processors.csrf
in yourCONTEXT_PROCESSORS
setting.https://docs.djangoproject.com/en/dev/ref/contrib/csrf/
Or add the token to your context manually
只需将其添加到您的视图中
return render_to_response("register.html", {'form': form, }, context_instance = RequestContext(request))
就可以了!
Just add this to your views
return render_to_response("register.html", {'form': form, }, context_instance = RequestContext(request))
It will work!!
尝试使用 render 而不是 render_to_response:
Django - render()、render_to_response() 和 direct_to_template() 之间有什么区别?
如前所述在上面的链接中,它是在 Django 1.3 中引入的,并自动使用 RequestContext
Try using render instead of render_to_response:
Django - what is the difference between render(), render_to_response() and direct_to_template()?
As stated in the link above it was introduced in Django 1.3 and automatically uses RequestContext
对于 Django 版本 3.0 添加以下注释
并且不要忘记在您的字段中添加以下标签
for Django version 3.0 add the below annotation
And don't forget add the below tag in your field
如果您不使用 CsrfViewMiddleware,则必须在使用 csrf_token 模板标记的任何视图以及接受 POST 数据的视图上使用 csrf_protect。
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
正如 @Yuji 'Tomita' Tomita 和 @Njogu Mbau 提到的,使用
render_to_response
时,添加RequestContext
是关键。然而,当我在解决这个问题时,最初让我感到困惑的是,我必须将RequestContext
添加到views.py
中最初加载模板的函数中,并添加到views.py
中处理模板提交的函数。另外,仅供参考,这里还有一些讨论同一问题的其他链接
The addition of
RequestContext
is the key when usingrender_to_response
as mentioned by @Yuji 'Tomita' Tomita and @Njogu Mbau. However, what initially threw me off when I was struggling with this problem was that I had to addRequestContext
to both the function inviews.py
that initially loads the template and to the function inviews.py
that handles the submission from the template.Also, just for reference, here are some other links that discuss this same problem
我安装 django-livereload-server 后,在某些页面上也随机出现此错误。卸载 django-livereload-server 就可以了。
Also got this error randomly on some pages after I installed django-livereload-server. Uninstalling django-livereload-server did the trick.
我也遇到了这个问题,但老实说,几分钟后我在浏览器上刷新,没有进行任何更改,当时它就有效了。我的命令行中有此消息,因此它可能会提供有关导致问题的原因的线索:
I had this issue too, but honestly, I hit refresh on my browser a few minutes later without changing anything and it worked that time. I had this message in my command line as so it might provide a clue as to what was causing the issue:
DJANGO/AJAX 工作流程完整方法就在这里:)
希望它能起作用!!!
DJANGO/AJAX WORKFLOW FULL METHOD IS HERE :)
Hope It Will Work !!!
中注释掉以下行
对我有用的是从我的
settings.py
'django.middleware.csrf.CsrfViewMiddleware'
What worked for me was commenting out the below line from my
settings.py
'django.middleware.csrf.CsrfViewMiddleware'