Forbidden (403) CSRF 验证失败.请求中止.即使使用 {% csrf_token %} [英] Forbidden (403) CSRF verification failed. Request aborted. Even using the {% csrf_token %}

查看:51
本文介绍了Forbidden (403) CSRF 验证失败.请求中止.即使使用 {% csrf_token %}的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 django 中登录,但出现此错误,我查看了 CSRF 文档,但没有任何效果.

这是 HTML:

<section class="容器"><div class="登录"><h1>登录到 Web 应用程序</h1>{% if form.errors %}<p class="error">Lo sentimos, la combinacion de usuario y contrasena no es Correcta!</p>{% 万一 %}<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="用户名"></p><p><input name="password" type="password" name="password" value="" placeholder="密码"></p><p class="submit"><input type="submit" name="commit" value="登录"></p></表单>

就像你在上面看到的那样,我使用了 {% csrf_token %},并且在我安装的应用程序中有django.middleware.csrf.CsrfViewMiddleware".

我的观点是:

from django.http import HttpResponse,HttpResponseRedirect从 django.template.loader 导入 get_template从 django.template 导入上下文从日期时间导入日期时间从 django.shortcuts 导入 render_to_response从 django.http 导入 HttpResponseRedirect从 django.contrib 导入身份验证从 django.core.context_processors 导入 csrf从模型导入 *从 django.shortcuts 导入 get_object_or_404从表单导入 *从 django.template.context 导入 RequestContext从 django.contrib.auth.decorators 导入 login_required从 django.contrib.auth 导入身份验证,登录定义登录(请求):c = {}c.更新(csrf(请求))return render_to_response('login.html', c)def auth_view(请求):用户名 = request.POST['用户名']密码 = request.POST['密码']用户 = 身份验证(用户名 = 用户名,密码 = 密码)如果用户不是无:auth.login(request.user)return HttpResponse('/accounts/loggedin')别的:return HttpResponse('/accounts/invalid')

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

解决方案

理论


要使 csrf 保护工作需要做一些事情(查看 docs):

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

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

你应该没事.

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

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

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

修复


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

{% csrf_token %}(...)</表单>

我们希望 csrf 字段在 ... 内,而不是 inside

.由于代码是目前,它将被转换为

我们宁愿

<input type='hidden' name='csrfmiddlewaretoken' value='randomchars'/>

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

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

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

i am trying to do a login in django but i get this error, i check the CSRF documentation and nothing works for me.

Here is the 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>

Like you see above i use the {% csrf_token %} and i have 'django.middleware.csrf.CsrfViewMiddleware' in my installed apps.

And my views are:

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')

i redirect to an other HTML file where i dont use the {% csrf_token %}.

解决方案

Theory


A couple of things are required to make the csrf protection work (check out the docs):

  1. Your browser has to accept cookies from your server
  2. Make sure you have 'django.middleware.csrf.CsrfViewMiddleware' included as middleware in your settings.py (alternatively use the decorator csrf_protect() on particular views you want to protect)
  3. Make sure you pass on the csrf token from django.core.context_processors.csrf to the context manager.

When you load your page, have a look in the page source using your favorite browser. Don't open the template html file, open the url which point to the view containing the form. Look at where you placed the {% csrf_token %}. If you see something like

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

you should be ok.

If you on the other hand see NOTPROVIDED, something has gone wrong while creating the csrf token. By looking in the source code (context_processors.py and csrf.py), we can find out what:

  • csrf(request) returns {'csrf_token': 'NOTPROVIDED'} if get_token(request) returns None.
  • get_token(request) returns request.META.get("CSRF_COOKIE", None).

I assume this means that it would return None if the cookie isn't successfully created.

Fix


For you, this means that you should first replace

<form action="/accounts/auth/" method="post" {% csrf_token %}>

with

<form action="/accounts/auth/" method="post">
{% csrf_token %}
(...)
</form>

We'd like the csrf field to be inside <form>...</form>, not inside <form>. As the code is at the moment, it will be converted to

<form action="/accounts/auth/" method="post" <input type='hidden' name='csrfmiddlewaretoken' value='randomchars' />>

and we would rather like

<form action="/accounts/auth/" method="post">
<input type='hidden' name='csrfmiddlewaretoken' value='randomchars' />

After that - have a look at the source code, and see if you can find the csrf field. If you can see it, everything should work in theory.

You can also check that the csrf cookie has been set in your browser, e.g. in Chrome, right-click the web page, and select Insepect Element. Select the Resources tab, and click on cookies. You should find a cookie name csrftoken there.

If you still have problems, double-check the middleware tuple in your settings.py and double-check that your browser accept cookier from your server as described above.

这篇关于Forbidden (403) CSRF 验证失败.请求中止.即使使用 {% csrf_token %}的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆