zoukankan      html  css  js  c++  java
  • ☆Django☆---中间件 csrf跨站请求伪造 auth模块 settings功能插拔式源码

    Django中间件

    django生命周期图

     中间件:

      概念: Django中间件就类似于 django的保安  

          请求 的时候需要先经过中间件才能到达django后端(urls, views)

          响应 走的时候也需要经过中间件才能到达web服务网关接口

      django默认的七个中间件

    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',
                                ]

        问:django中间件都可以用来干什么?  ***

      1. 网站全局的身份校验, 访问频率限制,权限校验.....

      2.django的中间件是web框架中 做的最好的

      Django中间件中有五个用户可以自定义的方法

       process_response  process_request  process_view  process_exception  process_templates

      如何自定义?

      ①首先需要在 app 同级目录下 创建你自己的 middleware 在里面创建你的py文件

      ②导入模块  from django.utils.deprecation import MiddlewareMixin

      ③定义自己的类 需要继承 Middleware 重写 上面五种方法

      ④在settings配置文件中的MIDDLEWARE 字符串点的方式 添加 例如: '文件夹.py文件.类名'

      process_request(request) 方法

        规律: 1.请求来的时候 会经过每一个中间件里面的 process_request方法(从上往下)

            2.如果方法里面直接返回了HttpResponse对象 那么会不在往下执行 放回同级 执行process_response方法 往回走

            3.方法 必须要传入request参数 也就是说 基于该特点 就可以做访问频率 身份校验,权限的校验

     

        process_response(request, response) 方法

          规律:1.必须将参数 reponse返回 因为这个参数就是 后端返回给前端的数据

             2.响应走的时候 会依次经过每一个中间件里面的 process_response方法(从下往上)

        

        了解方法:

        process_view(request, view_func,view_args, view_kwargs)   

        在路由匹配成功后 执行函数触发之前触发

        

        view_func 就是 url匹配对应的 视图函数 view_args 和 view_kwargs 都是参数

       process_exception( request,exception)

       当你的视图函数报错的时候回自动触发

       

          process_template_response(request, response)

       当你放回的HttpResponse对象中必须包含 render 属性 才会触发

       

         总结: 书写中间件的时候 只要形参中有response 就把它返回 他是 前端需要的数据

    csrf跨站请求伪造

         引入:钓鱼网站: 通过制作一个跟正儿八经的网站一模一样的界面 骗取用户输入信息 修改数据去正儿八经的网站提交

         内部原理: 在让用户输入给对方转账的那个input框上做手脚 不给 这个input 设置name 和属性   在内部隐藏一个写好的name 和 value属性input框 这个value就是 钓鱼网站受益人的账号  form 表单数据提交 改为正儿八经的 

       防止钓鱼网站的思路
          网站会给返回给用户的form表单页面 偷偷塞一个随机字符串
          请求到来的时候 会先比对随机字符串是否一致 如果不一致 直接拒绝(403)

          该随机字符串有以下特点
          1.同一个浏览器每一次访问都不一样
          2.不同浏览器绝对不会重复

    -------------------------------------------------------------------------------------------------------------------------------------------

       1.form表单发送post请求的时候 需要你仅仅做的就是写一句话 {{% csrf_token %}}

       

       这样我们就可以吧 中间件的有个注释打开了    他这个就是来校验你有没有 一个 csrfmiddlewaretoken的东西 没有直接给你403

      

         2.ajsx发送post请求的时候 如和避免csrf校验

       1.先在页面上写{% csrf_token %},  利用标签name 属性查找器 查找  获取到该input键值信息

      

       

      2.直接书写'{{ csrf_token }}'

      

        3.将获取随机键值对的方法写到一个js文件中 之后只需要导入文件即可  

      在static文件中创建 js文件 和 py文件 把下面代码写入 之后导入就行

    function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    var csrftoken = getCookie('csrftoken');
    
    
    function csrfSafeMethod(method) {
      // these HTTP methods do not require CSRF protection
      return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    
    $.ajaxSetup({
      beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
          xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
      }
    });

      之后 该怎么传就怎么传就行了

    1.当你网站全局都需要校验csrf的时候 有几个不需要校验该如何处理?

    2.当你网站全局不校验csrf的时候 有几个需要校验又该如何处理?

    from django.views.decorators.csrf import csrf_exempt,csrf_protect
      csrf_exempt 不校验 
    csrf_protect 只校验

       cbv装饰

    from django.utils.decorators import method_decorator
    这两个装饰器在给CBV装饰的时候 有一定的区别
                如果是csrf_protect 那么有三种方式
                    # 第一种方式
                    # @method_decorator(csrf_protect,name='post')  # 有效的
                    class MyView(View):
                        # 第三种方式
                        # @method_decorator(csrf_protect)
                        def dispatch(self, request, *args, **kwargs):
                            res = super().dispatch(request, *args, **kwargs)
                            return res
    
                        def get(self,request):
                            return HttpResponse('get')
                        # 第二种方式
                        # @method_decorator(csrf_protect)  # 有效的
                        def post(self,request):
                            return HttpResponse('post')
    如果是csrf_exempt 只有两种(只能给dispatch装)   特例
                @method_decorator(csrf_exempt,name='dispatch')  # 第二种可以不校验的方式
                class MyView(View):
                    # @method_decorator(csrf_exempt)  # 第一种可以不校验的方式
                    def dispatch(self, request, *args, **kwargs):
                        res = super().dispatch(request, *args, **kwargs)
                        return res
    
                    def get(self,request):
                        return HttpResponse('get')
    
                    def post(self,request):
                        return HttpResponse('post')

    装饰器中只有csrf_exempt是特例,其他的装饰器在给CBV装饰的时候 都可以有三种方式
    def login_auth(func):
        @wraps(func)
        def inner(request,*args,**kwargs):
            # 从request中获取cookie
            # print(request.path)
            # print(request.get_full_path())
            target_url = request.get_full_path()
            if request.COOKIES.get('name'):
                res = func(request,*args,**kwargs)
                return res
            else:
                return redirect('/lg/?next=%s'%target_url)
        return inner
    cookies装饰器

    auth模块

       引入: (如果你想用auth模块 那么就用全套) auth模块是跟用户相关的功能模块

       ①执行数据库迁移命令后 会产生很多的表 其中的auth_uesr 就是一张用户相关的表格

       ②添加数据 createsuperuser 创建超级用户 这个超级用户可以拥有登录django admin后台的权限

       

          设置邮箱 用户名 和 密码 auth_user 表中就会把你的数据记录下来 且以可登录 admin

    auth模块功能

      模块的导入

    from django.contrib import auth

      直接子啊视图函数使用 

      查询用户 

      user_obj = auth.authenticate(username='xxx', password='xxx')  

      

      记录用户状态

      auth.login(request,user_obj)

      

       

     

     

     

     

  • 相关阅读:
    保持URL不变和数字验证
    centOS ftp key?
    本地环境测试二级域名
    linux 解决You don't have permission to access 问题
    php smarty section loop
    php header Cannot modify header information headers already sent by ... 解决办法
    linux部分命令
    Linux 里面的文件操作权限说明
    用IT网络和安全专业人士视角来裁剪云的定义
    SQL Server 2008 R2炫酷报表"智"作有方
  • 原文地址:https://www.cnblogs.com/lddragon/p/11587823.html
Copyright © 2011-2022 走看看