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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20895526/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 21:29:09  来源:igfitidea点击:

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

pythondjangologincsrf

提问by BismarthSantana

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

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

Here is the HTML:

这是 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.

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

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 %}.

我重定向到我不使用 {% csrf_token %} 的其他 HTML 文件。

回答by Steinar Lima

Theory

理论



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

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

  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.csrfto the context manager.
  1. 您的浏览器必须接受来自您服务器的 cookie
  2. 确保您已将 'django.middleware.csrf.CsrfViewMiddleware'作为中间件包含在您的settings.py(或者在要保护的特定视图上使用装饰器 csrf_protect())
  3. 确保将 csrf 令牌从django.core.context_processors.csrf上下文管理器传递。

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

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

<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.pyand csrf.py), we can find out what:

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

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

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

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

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

我们希望 csrf 字段在 inside <form>...</form>,而不是inside<form>。由于代码目前,它将被转换为

<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.

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

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 Resourcestab, and click on cookies. You should find a cookie name csrftokenthere.

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

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

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

回答by Pradeep

With Addition of above answer, Try Adding following lines in the views

添加上述答案后,尝试在视图中添加以下行

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

回答by Mohammad Etemaddar

Clear your browser cache and try again. Maybe it is using the CSRF token saved in cached cookie.

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