禁止 (403) CSRF 验证失败。请求中止。即使使用 % csrf_token %
Posted
技术标签:
【中文标题】禁止 (403) CSRF 验证失败。请求中止。即使使用 % csrf_token %【英文标题】:Forbidden (403) CSRF verification failed. Request aborted. Even using the % csrf_token %禁止 (403) CSRF 验证失败。请求中止。即使使用 % csrf_token % 【发布时间】:2014-01-20 15:26:30 【问题描述】:我正在尝试在 django 中登录,但出现此错误,我检查了 CSRF 文档,但没有任何用处。
这是 html:
<body>
<section class="container">
<div class="login">
<h1>Login to Web App</h1>
% if form.errors %
<p class="error">Lo sentimos, la combinacion de usuario y contrasena no es correcta!</p>
% endif %
<form action="/accounts/auth/" method="post">
% csrf_token %
<input type='hidden' name='csrfmiddlewaretoken' value='randomchars'/>
<p><input name="username" type="text" name="login" value="" placeholder="Username"></p>
<p><input name="password" type="password" name="password" value="" placeholder="Password"></p>
<p class="submit"><input type="submit" name="commit" value="Login"></p>
</form>
</div>
</body>
如您在上面看到的,我使用 % csrf_token % 并且在我安装的应用程序中有“django.middleware.csrf.CsrfViewMiddleware”。
我的观点是:
from django.http import HttpResponse,HttpResponseRedirect
from django.template.loader import get_template
from django.template import Context
from datetime import datetime
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.core.context_processors import csrf
from models import *
from django.shortcuts import get_object_or_404
from forms import *
from django.template.context import RequestContext
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login
def login(request):
c =
c.update(csrf(request))
return render_to_response('login.html', c)
def auth_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
auth.login(request.user)
return HttpResponse('/accounts/loggedin')
else:
return HttpResponse('/accounts/invalid')
我重定向到另一个我不使用 % csrf_token % 的 HTML 文件。
【问题讨论】:
我遇到了这个错误,即使使用 % csrf_token %。但是将render_to_response改为render后,就解决了。 【参考方案1】:理论
要使 csrf 保护起作用,需要做一些事情(查看docs):
-
您的浏览器必须接受来自您的服务器的 cookie
确保在
settings.py
中包含 'django.middleware.csrf.CsrfViewMiddleware'
作为中间件(或者在要保护的特定视图上使用装饰器 csrf_protect())
确保将 csrf 令牌从 django.core.context_processors.csrf
传递给上下文管理器。
当您加载页面时,请使用您喜欢的浏览器查看页面源代码。不要打开模板 html 文件,打开指向包含表单的视图的 url。查看您放置% csrf_token %
的位置。如果你看到类似的东西
<input type='hidden' name='csrfmiddlewaretoken' value="jdwjwjefjwdjqwølksqøwkop2j3ofje" />
你应该没事的。
另一方面,如果您看到NOTPROVIDED
,则在创建 csrf 令牌时出现了问题。通过查看源代码(context_processors.py
和 csrf.py
),我们可以发现:
get_token(request)
返回无,csrf(request)
返回 'csrf_token': 'NOTPROVIDED'
。
get_token(request)
返回request.META.get("CSRF_COOKIE", None)
。
我认为这意味着如果 cookie 没有成功创建,它将返回 None
。
修复
对你来说,这意味着你应该先替换
<form action="/accounts/auth/" method="post" % csrf_token %>
与
<form action="/accounts/auth/" method="post">
% csrf_token %
(...)
</form>
我们希望 csrf 字段位于 <form>...</form>
内部,而不是 内部 <form>
。由于目前的代码,它将被转换为
<form action="/accounts/auth/" method="post" <input type='hidden' name='csrfmiddlewaretoken' value='randomchars' />>
我们更愿意
<form action="/accounts/auth/" method="post">
<input type='hidden' name='csrfmiddlewaretoken' value='randomchars' />
之后 - 查看源代码,看看是否可以找到 csrf 字段。如果你能看到它,理论上一切都应该有效。
您还可以检查是否已在浏览器中设置 csrf cookie,例如在 Chrome 中,右键单击网页,然后选择 Insepect Element
。选择Resources
选项卡,然后单击cookies。您应该在那里找到一个 cookie 名称 csrftoken
。
如果您仍有问题,请仔细检查 settings.py
中的中间件元组,并仔细检查您的浏览器是否接受来自您的服务器的 cookie,如上所述。
【讨论】:
我做到了,但仍然一无所获,出现同样的错误。在我的观点中使用@csrf_exempt 但仍然没有任何反应 好的,但是发布的 HTML 来自 /accounts/login/ URL,所以当我点击提交(登录)按钮时,它会将我重定向到 /accounts/auth/ URL,它调用 auth_view 方法在我看来。我没有 /accounts/auth/ URL 的 HTML 文件。也许这就是问题所在……你怎么看? @BismarthSantana 我想要您在带有提交按钮的页面上获得的 html,然后在您喜欢的浏览器中单击查看 -> 源代码。 @BismarthSantana 我对我的答案进行了实质性编辑 - 请看一下。 帮助很大!做了你告诉我的一切,仍然有错误......我已经用我所做的一切更新了我的代码,你可以在上面看到它。我的浏览器也允许使用 cookie。【参考方案2】:加上以上答案,尝试在视图中添加以下行
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def somathing():
return something
【讨论】:
请注意,这不会使安全工作,而是删除此安全机制。 这是完美的解决方案。简单易行。 +1。【参考方案3】:清除浏览器缓存并重试。也许它正在使用保存在缓存 cookie 中的 CSRF 令牌。
【讨论】:
这对我有用。即使在没有表单的页面上,我也会收到该错误以上是关于禁止 (403) CSRF 验证失败。请求中止。即使使用 % csrf_token %的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Django 管理员登录给我 403 CSRF 错误?