这一节的login表单中点击提交提示CSRF验证失败

来源:9-4 dashboard搭建与管理员模块开发(4)

追蝴蝶的少年ww

2019-11-30

1.环境:

win10,django 2.1.2,Mako 1.1.0

2.问题现象:

9-4小节一分零三秒之前的dashboard 的代码功能实现都正常。

login 页面 get 方法显示正常,测试填写用户名和密码后,点击提交出现报错页面:

http://img1.sycdn.imooc.com/szimg/5de239cb085f8ddb07840138.jpg

3.错误代码:

(1)app\dashboard\views\auth.py:

from django.shortcuts import redirect
from django.views.generic import View
from app.libs.base_render import render_to_response

class Login(View):
    TEMPLATE = 'dashboard/auth/login.html'

    def get(self, request):
        return render_to_response(request, self.TEMPLATE)

    def post(self, request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        print(username, password)
        return redirect('/dashboard/login')

(2)templates\dashboard\auth\login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login | 登录</title>
    <link href="/static/dashboard/css/bootstrap.min.css" rel="stylesheet" />
    <link rel="stylesheet" href="/static/dashboard/css/login.css">
</head>
<body>
<form class="form-horizontal edit-area" action="login" method="POST">
  <div class="form-group">
  <div class="col-sm-10">
    <input type="text" name="username" class="form-control" placeholder="用户名">
  </div>
  </div>
  <div class="form-group">
  <div class="col-sm-10">
    <input type="password" name="password" class="form-control" placeholder="密码">
  </div>
  </div>
  <div class="form-group">
      <div class="col-sm-offset-2 colsm-10">
          <button type="submit" class="btn btn-default">登录</button>
      </div>
  </div>
</form>
</body>
</html>

(3)app\libs\base_renderr.py

from mako.lookup import TemplateLookup
from django.template import RequestContext
from django.conf import settings
from django.template.context import Context
from django.http import HttpResponse


def render_to_response(request, template, data=None):
    """与jinjia2不同,mako的模板需要自己定义,于是有了本页的代码"""
    context_instance = RequestContext(request)
    path = settings.TEMPLATES[0]['DIRS'][0]

    lookup = TemplateLookup(
        directories=[path],
        output_encoding='utf-8',
        input_encoding='utf-8',
    )

    mako_template = lookup.get_template(template)

    if not data:
        data = {}

    if context_instance:
        context_instance.update(data)
    else:
        context_instance = Context(data)

    result = {}

    for d in context_instance:
        result.update(d)

    result['csrf_token'] = (
        '<input type="hidden" '
        'name="csrfmiddlewaretoken" '
        'value="{0}" />'.format(
            request.META.get('CSRF_COOKIE', '')),)

    return HttpResponse(mako_template.render(**result))



写回答

4回答

Singularity奇点

2019-11-30

#按照老师的方法已经解决了,以下是代码

from django.conf import settings
from django.http import HttpResponse
from django.middleware.csrf import get_token
from django.template import RequestContext
from django.template.context import Context
from mako.lookup import TemplateLookup

def render_to_response(request, template, data=None):
   context_instance = RequestContext(request)
   path = settings.TEMPLATES[0]['DIRS'][0]
   lookup = TemplateLookup(
       directories=[path],
       output_encoding='utf-8',
       input_encoding='utf-8'
   )   mako_template = lookup.get_template(template)   
   if not data:
       data = {}   
   if context_instance:
       context_instance.update(data)
   else:
       context_instance = Context(data)   result = {}   for d in context_instance:
       result.update(d)
   result['request'] = request
   request.META["CSRF_COOKIE"] = get_token(request)
   result['csrf_token'] = ('<div style="display:none">'
                           '<input type="hidden" '
                           'name="csrfmiddlewaretoken" '
                           'value="{0}"/>'
                           '</div>'.format(request.META["CSRF_COOKIE"]))   
   return HttpResponse(mako_template.render(**result))


5
7
幕布斯0444199
回复
deweizhang
老师mako模板 form表单的action不能用类似 {% url'viewname' %}的写法了吗
2020-05-19
共7条回复

阿君的猫

2020-07-28

我最近在学,也遇到了问题,刚刚找到了一个很好的解决方法

在重构mako的render中导入一个模块

from django.template.context_processors import csrf

result['csrf_token'] = ('<div style="display:none">'

                           '<input type="hidden" '

                           'name="csrfmiddlewaretoken" '

                           'value="{0}"/>'

                           '</div>'.format(request.META["CSRF_COOKIE"]))  

这句改为下面的:

result['csrf_token'] = '<input type="hidden" id="django-csrf-token" name="csrfmiddlewaretoken" value={0} />'.format(csrf(request)["csrf_token"])


就可以解决了,我发现csrf(request)["csrf_token"]是一个加密的串,也就是csrf的串

3
0

慕虎4249352

2020-05-23

login.html中添加${csrf_token}可以解决,但页面上又多出了一个('',)

//img.mukewang.com/szimg/5ec8ffc709ee0d3f06460334.jpg

0
0

deweizhang

2019-11-30

这个问题可以到群里和大家聊一下 我今天下午已经给出了解决方案 这应该是django的一个bug

0
4
deweizhang
回复
追蝴蝶的少年ww
恩行,我之后改一下git上的代码,坐下兼容~我加上备注 预计周一改一下 ~
2019-11-30
共4条回复

Django入门到进阶-适合Python小白的系统课程

入门Django的同时,让你形成更贴近实际工作的Python Web开发知识体系

1123 学习 · 475 问题

查看课程