繁体   English   中英

禁止(403)CSRF验证失败。 请求中止。 即使使用{%csrf_token%}

[英]Forbidden (403) CSRF verification failed. Request aborted. Even using the {% csrf_token %}

我正在尝试在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保护起作用,需要做一些事情(请参阅docs ):

  1. 您的浏览器必须接受服务器中的Cookie
  2. 确保您的settings.py已将“ django.middleware.csrf.CsrfViewMiddleware'作为中间件包括在内(或者在要保护的特定视图上使用装饰器csrf_protect())
  3. 确保将csrf令牌从django.core.context_processors.csrf传递到上下文管理器。

加载页面时,请使用喜欢的浏览器查看页面源。 不要打开模板html文件,请打开指向包含表单的视图的URL。 查看放置{% csrf_token %} 如果您看到类似

<input type='hidden' name='csrfmiddlewaretoken' value="jdwjwjefjwdjqwølksqøwkop2j3ofje" />

你应该没事的。

另一方面,如果您看到NOTPROVIDED ,则在创建csrf令牌时出现了问题。 通过查看源代码( context_processors.pycsrf.py ),我们可以找到以下内容:

  • 如果get_token(request)返回None,则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字段。 如果您能看到它,那么一切都应该在理论上起作用。

您还可以检查浏览器(例如Chrome)中是否设置了csrf cookie,右键单击网页,然后选择Insepect Element 选择Resources选项卡,然后单击cookie。 您应该在那里找到一个cookie名称csrftoken

如果您仍然有问题,仔细检查你的中间件元组settings.py并仔细检查您的浏览器如上所述从服务器接受cookier。

清除浏览器缓存,然后重试。 也许它使用保存在缓存cookie中的CSRF令牌。

通过上述答案的补充,尝试在视图中添加以下行

from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def somathing():
   return something

暂无
暂无

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

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