zoukankan      html  css  js  c++  java
  • DRF认证、权限、频率组件。

    一:基本知识

        1:该三个组件阅读源码的方式和版本源码阅读步骤类似。详细阅读版本源码https://www.cnblogs.com/yingjp/p/10606698.html

        2:进入initial可以看到以下方法

            #认证执行的方法
            self.perform_authentication(request)
            #权限执行的方法
            self.check_permissions(request)
            #频率执行的方法
            self.check_throttles(request)
    

     3:进一步对上述的方法进行阅读我们能得出以下几点。

         a:在settings中应该怎样配置

         b:自定义组件需要实现什么方法

         c:方法的返回值

         d:对应的属性取值的方法 

       4:对认证,权限,频率这三个逐渐学习步骤

           a:用rest_framework给我们提供的模块进行定制

           b:自己定义组件

    二:认证组件

          1:阅读源码结论

             a:认证类需要继承BaseAuthentication类

             b:需要实现authenticate(self, request)方法

             c:返回一个长度为2的元祖。

             d:settings可以通过'DEFAULT_AUTHENTICATION_CLASSES'配置全局的验证。

          2:自定义认证类(配置全局认证)

               a;先写一个认证类

    from  rest_framework.authentication import BaseAuthentication
    from testDemo.models import UserInfo
    from rest_framework.exceptions import AuthenticationFailed
    
    '''
    这里是写的token是存在url中
      1:需要继承BaseAuthentication
      2:需要重写authenticate()方法
      3:返回一个元祖
    '''
    
    class  MyAuth(BaseAuthentication):
        #自定义token在url中
        def authenticate(self, request):
            token = request.query_params.get('token','')
            user=UserInfo.objects.filter(token=token).first()
            if not user:
                raise AuthenticationFailed('token 信息不合理')
    
            return (user,token)
    

        b:settings注册

               --所有的视图函数都会进行认证,其实还不是很必要。局部认证在下面写

      

    REST_FRAMEWORK={
        #认证注册
        'DEFAULT_AUTHENTICATION_CLASSES':['utils.auth.MyAuth',],
    }
    

      3:使用rest_framework提供的认证组件进行认证。

              说明:认证组件一般都是自己写的,这里介绍自定义组件只是了解,学习视图函数的局部认证。          

              a:通过BaseAuthentication这个认证的基类,点进去就能看见所有人认证类了。使用方式和自定义的认证类一样

            b:局部视图的认证,在需要认证的视图处添加authentication_classes=[authclass1,authclass2]

    from utils.auth import MyAuth
    # Create your views here.
    from rest_framework.views import APIView,Response
    import uuid
    from testDemo.models import UserInfo
    # Create your models here.
    class authDemo(APIView):
        authentication_classes = [MyAuth, ]
        def get(self, request):
            print(request.user)
            print(request.auth)
            return Response('测试代码')  

    三:权限组件

        1:阅读代码结论

           1:settings全局配置 key'DEFAULT_PERMISSION_CLASSES'

           2:视图函数局部配置参数 permission_classes

           3:权限类需要继承的类 from rest_framework.permissions import BasePermission

           4:需要重写的方法 has_permission(self, request, view):

        2:自定义权限类

    from rest_framework.permissions import BasePermission
    
    class   MyPermissions(BasePermission):
        def   has_permission(self, request, view):
            #登陆成功后登陆信息,存在request.user中
            user_obj =request.user
            #type ==3 普通用户  没有该权限
            if user_obj.type ==3:
                return False
            return True
    

     3:权限配置:       

           参考第一条。略 

    四:频率组件

      说明:为了防止恶意访问,需要对同一个访问者进行访问频率控制,来减少服务器压力。

      1:频率组件实现原理

        DRF频率控制是通过单位时间内访问的次数来实现。在DRF的内部有一个字典,当一个iP访问的时候,如果IP1是已经访问的ip则在记录字典中添加这次的访问时间。

        {'ip1':[时间1,时间2,最新时间]}。如果IP2是第一次访问,则该字典进行添加操作{'ip2':[最新访问时间]}

     2:源码阅读结论(略)

          --小结会总结源码快捷阅读技巧。

     3:自定义频率控制类

    from rest_framework.throttling import BaseThrottle
    import time
    VISIT_RECORD = {}
    class   MyThrotting(BaseThrottle):
        def  __init__(self):
            self.history=[]
        #方法实现
        def allow_request(self, request, view):
            """
             以IP限流  一分钟同一个IP只能访问五次
            """
            #1:获取发访问一个ip
            ip = request.META.get("REMOTE_ADDR")
            '''
             2:判断当前ip是否存在,如果存在,添加最新的时间,如果不存在添加新的ip
            '''
            now_time=time.time()
            if  ip  in VISIT_RECORD:
                VISIT_RECORD[ip].insert(0,now_time)
            else:
                VISIT_RECORD[ip]=[now_time]
            history=VISIT_RECORD[ip]
            '''
            3:最后访问的和最新访问的时间相差一秒,删除最早访问的记录。保证字典内的记录均在一分钟以内。
            '''
            while history  and history[0]-history[-1]>60:
                history.pop()
            self.history=history
            """
            4:判断一分钟内,该ip访问次数是不是5次  
            """
            if len(history) > 5:
                return False
            else:
                return True
    
        def wait(self):
            """
            需要等待多长时间,才能再次访问
            """
            time = 60 - (self.history[0] - self.history[-1])
            return time
    

     4:局部配置和全局配置

           --略

     4:框架提供的频率认证组件的使用 

        1:导入包   

          --from rest_framework.throttling import SimpleRateThrottle

        2:settings配置

              --其他一些符号代表的时间频率

              --('s', 'sec', 'm', 'min', 'h', 'hour', 'd', 'day')

    REST_FRAMEWORK = {
        
        "DEFAULT_THROTTLE_RATES":{
            'WD':'5/m',         #速率配置每分钟不能超过5次访问,WD是scope定义的值,
    
        }
    }
    

        3:类的编写

    from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
    class MyVisitThrottle(SimpleRateThrottle):
        #与settings配置的一样
        scope = "WD"
    
        def get_cache_key(self, request, view):
            return self.get_ident(request)
    

        4:局部使用   

    class authDemo(APIView):
        throttle_classes=[MyVisitThrottle]
        def get(self, request):
            return Response('测试代码')
    

      

    五:小结  

         1:源码快速阅读总结

           a:观察框架实现的组件,可以发现导入规律

              -- rest_framework.组件英文拼写 import Base英文拼写

    from rest_framework.throttling import BaseThrottle
    from rest_framework.authentication import BaseAuthentication
    from rest_framework.permissions import BasePermission
    

            b:点进对应的方法,下面均有不同的实现,但是可以看到需要重写什么方法。这样就能自定义组件了

       2:组件阅读源码快速配置

           a:setings一定配置 REST_FRAMEWORK={}

            一定要写

    REST_FRAMEWORK = {}
        

           a:进入视图继承类APIView

              --中文注释我自己写的,是不是正好可以得出中文注释结论

              --全局配置key是 = 后面的值,

              --局部配置在 = 前面的参数  

     renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
        parser_classes = api_settings.DEFAULT_PARSER_CLASSES
        '''
          权限认证
        '''
        authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
        '''
        频率认证
        '''
        throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
        '''
        权限认证
        '''
        permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
        content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
        metadata_class = api_settings.DEFAULT_METADATA_CLASS
        
        '''
        版本认证
        '''
        versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
    

      

             

             

              

        

  • 相关阅读:
    springboot mail 发送邮件
    颜色透明度16进制对照表
    Java基础系列之(三)
    QQ2010协议分析系列(五)
    QQ2010协议分析系列(四)
    QQ2010协议分析系列(三)
    QQ2010协议分析系列(二)
    QQ2010协议分析系列(一)
    Java基础系列之(二)
    Java基础系列之(一)
  • 原文地址:https://www.cnblogs.com/yingjp/p/10608968.html
Copyright © 2011-2022 走看看