Django --CSRF 令牌丢失或不正确

Posted

技术标签:

【中文标题】Django --CSRF 令牌丢失或不正确【英文标题】:Django --CSRF token missing or incorrect 【发布时间】:2012-09-25 17:27:43 【问题描述】:

所以我得到了 Forbidden (403) CSRF 验证失败。请求中止。失败原因:CSRF 令牌丢失或不正确。 我的中间件类中有“django.middleware.csrf.CsrfViewMiddleware”。 这是我的模板

<form name="input" action="/login/" method="Post"> % csrf_token %
<input type="submit" value="Submit"></form>

这是我的看法

from django.shortcuts import render_to_response
from django.core.context_processors import csrf
from django.template import RequestContext
def login(request):
     csrfContext = RequestContext(request)
     return render_to_response('foo.html', csrfContext)

嗯,我是 Django 和大多数 Web 开发的新手,但我似乎无法在这里找到问题。任何帮助将不胜感激!

我也试过django文档中的方法

c = 
c.update(csrf(request))
# ... view code here
return render_to_response("a_template.html", c)

【问题讨论】:

附注:如果您是 Django 新手,我会考虑使用基于类的视图来处理几乎所有内容。即使您只是覆盖post,它们至少会强制服务器将响应哪些 HTTP 请求类型。 创建
的模板/视图是什么?
您需要在模板中添加% csrf_token %。并确保RequestContext 存在.. 当然,settings.py 中的相应中间件和.. 如果问题仍然存在。我不确定,但是.. 试试@csrf_exempt decorators.. 等等 【参考方案1】:

虽然禁用CSRF 令牌并手动获取CSRF 令牌值仍然有效。但是,在我的例子中,语法没有像 html 那样正确结构化,我们不必担心我们的脚本设计,但我认为在使用 jinja 时,即我们的模板语言很重要,是的,这就是我解决问题的方法。

【讨论】:

crpfcsrf 令牌【参考方案2】:

转到 urls 并在视图方法/类旁边添加 .as_view() 例如。

ObtainAuthTokenView.as_view()

【讨论】:

【参考方案3】:

只需将其添加到您的 HTML 中:

% csrf_token %

【讨论】:

虽然此解决方案不能回答上述问题,但它确实适用于发送没有 '% csrf_token %' 的表单的人【参考方案4】:

我和你有同样的问题,我发现这段代码可以解决我的问题。

from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render
from django.contrib import auth

#in accounts.forms i've placed my login form with two fields, username and password
from accounts.forms import LoginForm

@csrf_exempt
def login(request):
   if request.method == "POST":
      form = LoginForm(request.POST)
      if form.is_valid():
         user = auth.authenticate(
                username=form.cleaned_data["username"],
                password=form.cleaned_data["password"])
                auth.login(request, user)
                return HttpResponseRedirect("/")
      else:
         form = LoginForm()

return render(request, 'accounts/login.html', 'form':form)

【讨论】:

为此添加 csrf_exempt 不是必需的,这会使您的网站容易受到攻击。该装饰器适用于您特别需要此类请求、意识到风险并采取其他预防措施的边缘情况。【参考方案5】:

尝试在登录函数之前添加 @csrf_protect 装饰器。

from django.views.decorators.csrf import csrf_protect

@csrf_protect
def login(request):
     csrfContext = RequestContext(request)
     return render_to_response('foo.html', csrfContext)

如果表单不在 foo.html 中,则需要将@csrf_protect 方法添加到生成它的视图函数中。

【讨论】:

试过了还是报同样的错误,也试过上面的建议,修复了render_to_response语法... 问题可能是您从另一个页面发布到 /login/ 并且另一个页面上没有 @csrf_protect 吗?您评论中的模板文本来自哪个页面?查看正在生成的 HTML 并验证其中是否包含 csrf_protect 令牌。【参考方案6】:

您应该执行以下操作:

def login(request):
     context = 
     request_context = RequestContext(request)
     return render_to_response('foo.html', context,
                               request_context=request_context)

这里是official docs 代表render_to_response

【讨论】:

仍然出现同样的错误,我也尝试使用 @csrf_protect 装饰器,但没有任何改进... 在您的 html 中,您是否看到了 csrf 令牌?如果没有,请尝试添加 requires_csrf_token 装饰器。

以上是关于Django --CSRF 令牌丢失或不正确的主要内容,如果未能解决你的问题,请参考以下文章

CSRF 令牌丢失或不正确。 Django + AngularJS

Django - 403 禁止。 CSRF 令牌丢失或不正确

Django:CSRF 令牌丢失或不正确。 / 避免 % csrf_token %

Django 表单中的 CSRF 令牌丢失或不正确

Unity Web Request + Django:CSRF 令牌丢失或不正确

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