【问题标题】:Django CSRF verification failed even after adding csrf_token tag inside the form html即使在表单 html 中添加 csrf_token 标记后,Django CSRF 验证也失败
【发布时间】:2018-12-06 07:36:53
【问题描述】:

我正在使用 Python(2.7) 和 Django(1.10) 开发一个项目,我需要在其中提交登录表单,但提交时返回错误。

注意:我搜索了很多问题尝试了各种答案,但在 大多数情况下,{% csrf_token %} 缺少 <form> HTML 但就我而言,我也在使用这个,这就是为什么不标记这个 请重复问题!

这是我尝试过的:

来自form.html

<form class="fields-signup" action="{% url 'mainlogin' %}" method="post">


{% csrf_token %}
            <h1 class="text-center">Sign In</h1>
            <div class="form-group">
                <input class="user-name form-control" type="text"  name="username" placeholder="User name">
            </div>
            <div class="form-group">
                <input class="password form-control" type="password"   placeholder="Password" name="password">
            </div>
            <input type="submit" class="btn siteBtn" value="Sign In">
            <!-- <a href="#" class="btn siteBtn" >Sign Up</a>
            <p class="text-center">Don’t Have an account? <a href="#">Signup</a></p> -->


            <!--popup-forget-password-->
            <div class="col-sm-12">
             <button type='button' class="forget-password-btn" data-toggle="modal" data-target="#popUpWindow">Forgot Password</button> 
              <!--forget-password-end-->
                <div class="col-sm-12 register">
                 <a class="register-driver-btn" data-toggle="modal" data-target="#popUpWindow_register">Register Driver?</a> 
                </div>
            </div>
</form>

来自urls.py

url(r'^$', views.home, name="home"),

来自views.py

    if request.method == "GET":
    try:
        temp = get_template('login.html')
        result = temp.render(Context({'context': RequestContext(request)}))
        return HttpResponse(result)

更多来自views.py

    if request.method == "POST":
    username = request.POST['username']
    # email = request.POST['email']
    password = request.POST['password']
    try:
        #obj = User_table.objects.get(user_name=username, emailid=email)
        obj = User_table.objects.get(user_name=username)
        if obj:
            print('got user obj')
        verify_password = ''
        try:
            verify_password = handler.verify(password, obj.password)
        except Exception as e:
            print(e)
        if verify_password is True:
            request.session['user_id'] = obj.id
            request.session['user_type'] = obj.user_type
            user_name = obj.first_name + ' ' + obj.last_name
            request.session['user_name'] = user_name
            if not obj.approval_status:
                return HttpResponse('Your account is not confirmed by administration.')
            obj.is_active = True
            obj.login_try = 0
            obj.save()
            return redirect(home)
        else:
            try:
                # obj = User_table.objects.get(user_name=username, emailid=email)
                obj = User_table.objects.get(user_name=username)
                if obj:
                    s = obj.login_try
                    s = s + 1
                    obj.login_try = int(s)

                    if int(obj.login_try) >= 3:
                        obj.login_try = 3
                    obj.save()
                    if int(obj.login_try) == 3:
                        id = obj.id
                        key = get_random_string(length=10)
                        reset_link = 'It seems you forgot password or someone is trying to login you account. This is your password reset link please do not share this with other ' + settings.EMAIL_URL + 'reset_password/' + str(
                            id) + ' key is : ' + str(key)
                        send_mail('Reset link', reset_link, settings.EMAIL_HOST_USER, [obj.emailid, ])
                        obj.password = str(key)
                        obj.save()
                        return HttpResponse(
                            'It seems you forgot password or someone is trying to login you account.  Password Reset link has been sent to your email id')
            except Exception as e:
                print(e)
                pass
            return redirect(mainlogin)
    except Exception as e:
        print('error is  : ', e)
        return HttpResponse('An error has occurred.')

另外,我在settings.py 中包含了csrf 中间件。 这里有什么问题?

提前致谢!

【问题讨论】:

  • 检查您的浏览器检查器(例如 chrome 开发者工具)并查看 post 请求数据中是否有 csrf_token。 + 查看是否有额外的&lt;input&gt; 以形式呈现。还从views.py粘贴更多,您发布的代码不清楚。
  • 您发布数据的视图在哪里
  • 嗨@Exprator,我也添加了post 的代码。请看一下!
  • 浏览器检查器显示发布数据为:password abd37214 username abdul002
  • 在您的 method == 'GET' 部分将 3 行更改为单行:return render(request, 'login.html') 导入为:from django.shortcuts import render。这对你有用吗?

标签: python django python-2.7 django-csrf


【解决方案1】:

你的问题在这里:

if request.method == "GET":
    try:
        temp = get_template('login.html')
        result = temp.render(Context({'context': RequestContext(request)}))
        return HttpResponse(result)

Docs about CSRF

在相应的视图函数中,确保RequestContext是 用于呈现响应,以便 {% csrf_token %} 可以工作 适当地。如果您使用的是 render() 函数、通用视图或 contrib 应用程序,你已经被覆盖,因为这些都使用 请求上下文。

我不确定为什么会发生这种情况,可能是上下文处理器配置有问题,其中一个将 csrf_token 添加到上下文字典中。 有关更多调试,请参阅RequestContext 部分。但是使用内置的render() 函数将解决您的问题,因为它会为您处理上下文。

from django.shortcuts import render
if request.method == "GET":
    ...
    return render(request, 'login.html')

【讨论】:

  • 使用请求渲染模板的正确方法是temp.render(request=request),但按照您的建议使用render 快捷方式更简单。
猜你喜欢
  • 2012-01-14
  • 2018-03-10
  • 1970-01-01
  • 2017-10-20
  • 2016-09-09
  • 2014-01-20
  • 1970-01-01
  • 2020-03-05
  • 1970-01-01
相关资源
最近更新 更多