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)

      

       

     

     

     

     

  • 相关阅读:
    原型链
    computed>watch>methods;methods>watch
    rem
    Cookie、Session、Token
    :(){:|:&};:
    js匹配多选框选中项
    sass自备了一系列的函数功能。
    字符串
    ECMAScript6 入门教程记录之-编程风格
    const命令
  • 原文地址:https://www.cnblogs.com/lddragon/p/11587823.html
Copyright © 2011-2022 走看看