zoukankan      html  css  js  c++  java
  • django学习之- CSRF及中间件

    CSRF # 表示django全局发送post请求均需要字符串验证
    功能:防止跨站请求伪造的功能
    工作原理:客户端访问服务器端,在服务器端正常返回给客户端数据的时候,而外返回给客户端一段字符串,等到客户端下次访问服务器
    端时,服务器端会到客户端查找先前返回的字符串,如果找到则继续,找不到就拒绝。
    访问流程:客户端-》URL路由系统 - 》 CSRF -》视图函数
    需要在客户端页面的post表单内添加:{% csrf_token %}
    全局生效:
      中间件 django.middleware.csrf.CsrfViewMiddleware
    局部生效:
    @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
    @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
    写法如下:
    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    @csrf_exempt
    def index(request): # 这样表示此函数取消CSRF验证
    实例:登录页面通过ajax进行form表单提交
      <body>
    
        <div class="container">
    
          <form id='logfrom' class="form-signin">
           {% csrf_token %}
            <h2 class="form-signin-heading">主机管理页面</h2>
            <label for="inputusername" class="sr-only">用户名</label>
            <input type="text" id="inputusername" class="form-control" name="uname" placeholder="username" required="" autofocus=""><span class="nameinfo hide">用户名错误</span>
            <label for="inputPassword" class="sr-only">密码</label>
            <input type="password" id="inputPassword" class="form-control" name="upwd" placeholder="Password" required=""><span class="pwdinfo hide">密码错误</span>
            <div class="checkbox">
              <label>
                <input type="checkbox" value="remember-me"> Remember me
              </label>
            </div>
            <input id='login' class="btn btn-lg btn-primary btn-block" type="button" value="登录">
          </form>
    
        </div> <!-- /container -->
    
    
        <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
        <script src="/static/ie10-viewport-bug-workaround.js"></script>
        <script src="/static/jquery-1.12.4.min.js"></script>
        <script src="static/jquery-cookie/jquery.cookie.js"></script>
        <script>
            $('#login').click(function () {
                //以下的ajaxSetup为全局的csrf设置
                $.ajaxSetup({
    //             xhr为XmlHttpRequest 对象,是一个固定写法
                beforeSend: function (xhr, settings) {
                    /*这里settings代表下面将要执行的ajax里面的内容*/
    //                以下表示设置请求头
                    xhr.setRequestHeader('X-CSRFtoken', $.cookie('csrftoken'))
                }
            });
    
                $.ajax({
                    url:'/index',
                    type:'post',
                    data:{'logname':$('#inputusername').val(),'logpwd':$('#inputPassword').val()},
                    success:function (data) {
                        if (data == 'ok'){
                            location.href = '/index'
                        }if(data == 'nmerr'){
                            $('.nameinfo').removeClass('hide');
                        }if(data =='pwderr'){
                            $('.pwdinfo').removeClass('hide');
                        }
                    }
                })
            })
        </script>
        </body>
    View Code

    views函数中对应的函数设置

    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    @csrf_exempt
    def index(request):
    ........

    中间件

    可以定义5个方法:
    - process_request
    - process_view
    - process_response
    - process_exception # 做异常处理
    - process_template_response # 了解即可,如果views中的函数返回的对象中具有render方法,才执行这个函数
    适合对所有的请求做统一操作,(如:黑名单)
    游览器-URL -中间件-视图函数
    实例如:
    settings的MIDDLEWARE配置:
    'middle.MIDDLE.M1',
    'middle.MIDDLE.M2',
       'middle.MIDDLE.M3',
    模块MIDDLE文件内容
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    
    class M1(MiddlewareMixin):
        def process_request(self,request):
            print('中间件1')
        def process_view(self,request,view_func,view_func_args,view_func_kwargs):
            '''
            :param request: 请求数据
            :param view_func: 视图函数
            :param view_func_args: 视图函数参数
            :param view_func_kwargs: 视图函数参数
            :return:
            '''
            print('新添加中间件1')
        def process_response(self,request,response):
            print('中间件返回1')
            return response
        def process_exception(self,request,exception):
            ''' 当执行的视图函数运行出现错误,则执行此方法提示'''
            if isinstance(exception,ValueError):
                return HttpResponse('当前的view函数出现了异常,请检查')
    
        def process_template_response(self, request, response):
            # 如果试图函数views中的函数返回的对象中,具有render方法,才执行
            pass
            return response
    class M2(MiddlewareMixin):
        def process_request(self,request):
            print('中间件2')
        def process_view(self,request,view_func,view_func_args,view_func_kwargs):
            print('新添加中间件2')
        def process_response(self, request, response):
            print('中间件返回2')
            return response
    class M3(MiddlewareMixin):
        def process_request(self,request):
            print('中间件3')
        def process_view(self,request,view_func,view_func_args,view_func_kwargs):
            print('新添加中间件3')
        def process_response(self, request, response):
            print('中间件返回3')
            return response
    View Code

    请求流程:访问-》M1.process_request -> M2.process_request -> M3.process_request -> 返回
    M1.process_view -> M2.process_view -> M3.process_view -> 视图函数 -> M3.process_response->M2.process_response->M1.process_response
  • 相关阅读:
    树莓派frp添加为服务管理
    liunx开源打印驱动foo2zjs编译小坑
    树莓派中实现ll命令
    Windows中使用QEMU创建树莓派虚拟机
    C#打印条码BarTender SDK打印之路和离开之路(web平凡之路)(转)
    数据库连接池问题 Max Pool Size
    C#时间
    XAF 如何从Excel复制多个单元格内容到GridView(收藏)
    C#日期处理(转) 太忘记了,备忘
    C#、devExpress 的 给bandedGrid加菜单功能 :复制、粘贴的例子(转)
  • 原文地址:https://www.cnblogs.com/zy6103/p/8018242.html
Copyright © 2011-2022 走看看