简体   繁体   English

CSRF 令牌丢失或不正确

[英]CSRF Token missing or incorrect

Beginner at Django here, I've been trying to fix this for a long time now.这里是 Django 的初学者,我已经尝试解决这个问题很长时间了。 I do have 'django.middleware.csrf.CsrfViewMiddleware' in my middleware classes and I do have the token in my post form.我的中间件类中确实有“django.middleware.csrf.CsrfViewMiddleware”,并且我的帖子表单中确实有令牌。

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 %}

Update: This answer is from 2011. CSRF is easy today.更新:这个答案来自 2011 年。CSRF 今天很容易。

These days you should be using the render shortcut function return render(request, 'template.html') which uses RequestContext automatically so the advice below is outdated by 8 years.这些天你应该使用render快捷函数return render(request, 'template.html')它自动使用RequestContext所以下面的建议已经过时了 8 年。

  1. Use render https://docs.djangoproject.com/en/2.2/topics/http/shortcuts/使用render https://docs.djangoproject.com/en/2.2/topics/http/shortcuts/
  2. Add CSRF middleware https://docs.djangoproject.com/en/2.2/ref/csrf/添加 CSRF 中间件https://docs.djangoproject.com/en/2.2/ref/csrf/
  3. Use the {% csrf_token %} template tag使用{% csrf_token %}模板标签
  4. Confirm you see the CSRF token value being generated, AND submitted in your form request确认您看到正在生成的 CSRF 令牌值,并在您的表单请求中提交

Original 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?)我的猜测是您在模板中有标签,但它没有呈现任何内容(或者您的意思是您在实际的 HTML 中确认正在生成 CSRF 令牌?)

Either use RequestContext instead of a dictionary要么使用RequestContext而不是字典

render_to_response("foo.html", RequestContext(request, {}))

Or make sure you have django.core.context_processors.csrf in your CONTEXT_PROCESSORS setting.或者确保您的CONTEXT_PROCESSORS设置中有django.core.context_processors.csrf

https://docs.djangoproject.com/en/dev/ref/contrib/csrf/ https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

Or add the token to your context manually或者手动将令牌添加到您的上下文中

Just add this to your views只需将此添加到您的视图中

return render_to_response("register.html", {'form': form, }, context_instance = RequestContext(request))

It will work!!它会起作用!!

Try using render instead of render_to_response :尝试使用render而不是render_to_response

from django.shortcuts import render

render(request, "foo.html", {})

Django - what is the difference between render(), render_to_response() and direct_to_template()? Django - render()、render_to_response() 和 direct_to_template() 之间有什么区别?

As stated in the link above it was introduced in Django 1.3 and automatically uses RequestContext如上面的链接所述,它是在 Django 1.3 中引入的,并自动使用RequestContext

for Django version 3.0 add the below annotation对于 Django 3.0 版,添加以下注释

@csrf_protect
def yourfunc(request):
    return render(request, '../your.html', None)

And don't forget add the below tag in your field并且不要忘记在您的字段中添加以下标签

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

如果您没有使用 CsrfViewMiddleware,那么您必须在任何使用 csrf_token 模板标记的视图以及接受 POST 数据的视图上使用 csrf_protect。

The addition of RequestContext is the key when using render_to_response as mentioned by @Yuji 'Tomita' Tomita and @Njogu Mbau.加入RequestContext使用时是关键render_to_response通过@Yuji“富田”富田和@Njogu Mbau提及。 However, what initially threw me off when I was struggling with this problem was that I had to add RequestContext to both the function in views.py that initially loads the template and to the function in views.py that handles the submission from the template.然而,最初扔我什么,当我有这个问题挣扎的是,我不得不添加RequestContext到这两个功能views.py最初加载模板和功能在views.py处理来自模板提交。

Also, just for reference, here are some other links that discuss this same problem另外,仅供参考,这里有一些其他链接讨论同样的问题

Also got this error randomly on some pages after I installed django-livereload-server.安装 django-livereload-server 后,在某些页面上也随机出现此错误。 Uninstalling django-livereload-server did the trick.卸载 django-livereload-server 成功了。

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:我的命令行中有此消息,因此它可能会提供有关导致问题的原因的线索:

Not Found: /css/reset/reset.css
[03/Jul/2020 20:52:13] "GET /css/reset/reset.css HTTP/......

DJANGO/AJAX WORKFLOW FULL METHOD IS HERE :) DJANGO/AJAX 工作流程完整方法在这里:)

const url = "{% url 'YOUR_URL_NAME' pk=12345 %}".replace(/12345/, id.toString());
$.ajax({
        type: 'POST',
        url: url,
        data: {'id':id, "csrfmiddlewaretoken": '{{csrf_token}}'},
        beforeSend: function() { $('#response').text('Please wait ...'); },
        success: function (response) {
            console.log(response)           
        },
        error: function (response) {
            console.log(response)
        }
    })

Hope It Will Work !!!希望它会起作用!!!

对我有用的是从我的settings.py注释掉以下行

'django.middleware.csrf.CsrfViewMiddleware'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM