10

我正在制作登录表单的应用程序,但是当我运行我的应用程序并单击登录按钮时,将发生以下错误

禁止 (403) CSRF 验证失败。请求中止。

view.py 的代码如下:

from django.template import  loader
from django.shortcuts import render_to_response
from registration.models import Registration
from django.http import HttpResponse
from django.template import RequestContext
from django.shortcuts import redirect


def view_login(request,registration_id):
   t = loader.get_template('registration/login.html') 
   try:
         registration=Registration.objects.get(pk=registration_id)
   except Registration.DoesNotExist:
         return render_to_response("login.html",{"registration_id":registration_id})

def home(request,registration_id):
    if request.method == "POST":
      username = request.POST.get('user_name')
      password = request.POST.get('password')
      user = authenticate(username=username, password=password)
      if user is not None:
        if user.is_active:
          login(request, user)
        # success
          return render('registration/main_page.html',{'registration_id':registration_id},context_instance=RequestContext(user))
        else:
         #user was not active
           return redirect('q/',context_instance=RequestContext(user))
      else:
        # not a valid user
           return redirect('q/',context_instance=RequestContext(user))
    else:
       # URL was accessed directly
           return redirect('q/',context_instance=RequestContext(user))
4

6 回答 6

17

您需要{% csrf_token %}在表单中添加

https://docs.djangoproject.com/en/2.2/ref/csrf/

像那样 :

<form>
    {% csrf_token %}
    <anything_else>
</form>

此外,每次使用时都必须使用 RequestContext(request) render_to_response

return render_to_response("login.html",
    {"registration_id":registration_id},
    context_instance=RequestContext(request))

而且您必须导入身份验证和登录:

from django.contrib.auth import authenticate, login
于 2012-08-29T08:51:45.833 回答
2

我在使用“The Definitive Guide to Django”一书时遇到了这个问题,其中使用了 1.1 版。本书没有解决后续版本中强制要求的 csrf_token 验证需求。

要解决此问题,请添加:

from django.template import RequestContext

到 views.py 文件和 render_to_response 函数的这个添加参数:

context_instance = RequestContext(request)

一定要在模板{% csrf_token %}<form>标签内添加

于 2012-11-05T20:42:49.483 回答
2

只是评论 'django.middleware.csrf.CsrfViewMiddleware'

在您的settings.py 中,这对我有用:

//settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

除非您以其他方式管理 CSRF,否则这可能存在安全漏洞,并且不建议这样做,因为您将容易受到 CSRF 攻击

于 2016-08-30T04:00:43.937 回答
0

当您出现“禁止 (403) CSRF 验证失败。请求中止”时,您可以选择执行以下操作:

选项(2)(非首选)

进口:

from django.template.context_processors import csrf

添加到上下文:

context = {}
context.update(csrf(request))

返回:

-Django > 1.9 有“context”而不是“context_instance”

return render_to_response("login.html",
    {"registration_id":registration_id},
    context=context)

选项(3)(首选)

进口:

- 而不是导入“render_to_response”导入“render”

from django.shortcuts import render

返回:

return render(request, "login.html", context)

显然选项 3 更可取,因为“render”比“render_to_response”短,尤其是在您需要导入和添加内容时。我可以想象选项 2 保持更精简的上下文字典,但这似乎微不足道(?)。

为了清楚起见:

如上所述,这两种解决方案仍然需要您的 html 表单中的 {% csrf_token %}。并且永远不要关闭或评论 csrf middelware。

来源:

RequestContext 上的旧 Django 1.9 文档

csrf 处理器上的 Django 2 文档

解释渲染的来源就足够了

于 2018-07-26T09:00:53.833 回答
-1
method: 'POST',
headers: {
              'Content-Type': 'application/json',
              "X-CSRFToken": $("[name=csrfmiddlewaretoken]").val()
         },

{% csrf_token %} => add this inside header tag in html
于 2020-09-04T04:08:53.657 回答
-1

虽然这可能不是 OP 的问题,但我发现从 ezoic 添加验证代码实际上搞砸了我的 CSRF 流程。添加代码破坏了我的网站登录过程,可能还有其他形式。

于 2021-02-05T14:02:47.523 回答