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

Bis*_*ana 17 python django login csrf

我正在尝试登录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>
Run Code Online (Sandbox Code Playgroud)

就像你在上面看到的那样,我使用{%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')
Run Code Online (Sandbox Code Playgroud)

我重定向到另一个HTML文件,我不使用{%csrf_token%}.

Ste*_*ima 22

理论


要使csrf保护工作,需要做几件事(查看文档):

  1. 您的浏览器必须接受来自您服务器的cookie
  2. 确保你已经' django.middleware.csrf.CsrfViewMiddleware'包含在你的中间件中settings.py(或者在想要保护的特定视图上使用装饰器csrf_protect())
  3. 确保将csrf令牌传递django.core.context_processors.csrf给上下文管理器.

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

<input type='hidden' name='csrfmiddlewaretoken' value="jdwjwjefjwdjqwølksqøwkop2j3ofje" />
Run Code Online (Sandbox Code Playgroud)

你应该没事.

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

  • csrf(request)回报{'csrf_token': 'NOTPROVIDED'},如果get_token(request)回报无.
  • get_token(request)回报request.META.get("CSRF_COOKIE", None).

我认为这意味着None如果没有成功创建cookie ,它将返回.

固定


对你来说,这意味着你应该先替换

<form action="/accounts/auth/" method="post" {% csrf_token %}>
Run Code Online (Sandbox Code Playgroud)

<form action="/accounts/auth/" method="post">
{% csrf_token %}
(...)
</form>
Run Code Online (Sandbox Code Playgroud)

我们希望csrf字段在里面<form>...</form>,而不是在里面 <form>.由于代码目前正在转换为

<form action="/accounts/auth/" method="post" <input type='hidden' name='csrfmiddlewaretoken' value='randomchars' />>
Run Code Online (Sandbox Code Playgroud)

我们宁愿喜欢

<form action="/accounts/auth/" method="post">
<input type='hidden' name='csrfmiddlewaretoken' value='randomchars' />
Run Code Online (Sandbox Code Playgroud)

之后 - 查看源代码,看看是否可以找到csrf字段.如果你能看到它,一切都应该在理论上起作用.

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

如果您仍然遇到问题,请仔细检查您的中间件元组,settings.py并仔细检查您的浏览器是否接受了服务器中的cookier,如上所述.