zoukankan      html  css  js  c++  java
  • DRF的权限和频率

    DRF的权限

    权限组件源码

    权限和频率以及版本认证都是在initial方法里初始化的

    我们的权限类一定要有has_permission方法~否则就会抛出异常~~这也是框架给我提供的钩子~~

     在rest_framework.permissions这个文件中~存放了框架给我们提供的所有权限的方法~~

    主要说下BasePermission 这个是我们写权限类继承的一个基础权限类~~~ 

    权限的详细用法

    initial方法在初始化的时候是有顺序的:版本-->权限-->频率 

    写权限类

    class MyPermission(object):
        message = '权限不足'
    
        def has_permission(self, request, view):
            # 权限逻辑
            """
            自定义VIP用户权限,
            注意我们初始化时候的顺序是:版本-->权限-->频率 
            所以只要认证通过我们这里就可以通过request.user,拿到我们用户信息
            request.auth就能拿到用户对象
            """
            user_obj = request.user
            if user_obj.type == 1:
                return False
            else:
                return True

     局部视图注册

    class TestPermission(APIView):
        authentication_classes = [MyAuth, ]
        permission_classes = [MyPermission, ]
    
        def get(self, request):
            return Response('vip用户能看的电影')

    全局注册 settings.py

    REST_FRAMEWORK = {
        # 默认使用的版本控制类
        'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
        # 允许的版本
        'ALLOWED_VERSIONS': ['v1', 'v2'],
        # 版本使用的参数名称
        'VERSION_PARAM': 'version',
        # 默认使用的版本
        'DEFAULT_VERSION': 'v1',
        # 配置全局认证
        # 'DEFAULT_AUTHENTICATION_CLASSES': ["BRQP.utils.MyAuth", ]
        # 配置全局权限
        "DEFAULT_PERMISSION_CLASSES": ["BROP.utils.MyPermission"]
    }

     DRF的频率

    频率限制是做什么的

    开放平台的API接口调用需要限制其频率,以节约服务器资源和避免恶意的频繁调用。

    我们的DRF提供了一些频率限制的方法。

    频率组件源码

    版本、认证、权限、频率这几个组件的源码是一个流程。

    频率组件原理

    DRF中的频率控制基本原理是基于访问次数和时间的,当然我们可以通过自己定义的方法来实现。

    当我们请求进来,走到我们频率组件的时候,DRF内部会有一个字典来记录访问者的IP,

    以这个访问者的IP为key,value为一个列表,存放访问者每次访问的时间,

    {  IP1: [第三次访问时间,第二次访问时间,第一次访问时间],}

    把每次访问最新时间放入列表的最前面,记录这样一个数据结构后,通过什么方式限流呢~~

    如果我们设置的是10秒内只能访问5次,

      -- 1,判断访问者的IP是否在这个请求IP的字典里

      -- 2,保证这个列表里都是最近10秒内的访问的时间

          判断当前请求时间和列表里最早的(也就是最后的一个的)请求时间的差

          如果差大于10秒,说明请求已经不是最近10秒内的,删除掉,

          继续判断倒数第二个,直到差值小于10秒

      -- 3,判断列表的长度(即访问次数),是否大于我们设置的5次,

          如果大于就限流,否则放行,并把时间放入列表的最前面。

    频率组件的详细用法

    频率组件的配置方式其实跟上面的组件都一样。

    自定义的频率限制类

    import time
    
    VISIT_RECORD = {}
    
    
    class MyThrottle(object):
        """
        一分钟允许访问5次
        """
    
        def __init__(self):
            self.history = []
    
        def allow_request(self, request, view):
            # 获取用户的IP地址META   REMOTE_ADDR
            ip = request.META.get('REMOTE_ADDR', '')
            # 如果ip不在字典中
            if ip not in VISIT_RECORD:
                # 则ip作为key,当前时间作为value加入到VISIT_RECORD中
                VISIT_RECORD[ip] = [time.time(), ]
            # 如果ip在字典中
            else:
                history = VISIT_RECORD[ip]
                # 用self.history接一下变量
                self.history = history
                # 把最近访问的时间插入到列表的最前面
                history.insert(0, time.time())
                # 先确保列表时间是允许范围之内的
                while self.history[0] - self.history[-1] > 60:
                    self.history.pop()
                    # 判断列表长度
                if not len(self.history) <= 5:
                    return False
            return True
    
        # 等待信息
        def wait(self):
            # 超出访问频率后提示限制时间还剩多少
            return 60 - (self.history[0] - self.history[-1])

    配置自定义频率限制

    REST_FRAMEWORK = {
        # ......
        # 频率限制的配置
        "DEFAULT_THROTTLE_CLASSES": ["Throttle.throttle.MyThrottle"],
        }
    }

    使用自带的频率限制类

    from rest_framework.throttling import SimpleRateThrottle
    
    
    class DRFThrottle(SimpleRateThrottle):
        scope = 'WD'
    
        def get_cache_key(self, request, view):
            # 拿ip地址
            return self.get_ident(request)

    配置频率限制

    REST_FRAMEWORK = {
        # 频率限制的配置
        # "DEFAULT_THROTTLE_CLASSES": ["Throttle.throttle.MyVisitThrottle"],
        "DEFAULT_THROTTLE_CLASSES": ["Throttle.throttle.MyThrottle"],
        "DEFAULT_THROTTLE_RATES":{
            'WD':'5/m',         #速率配置每分钟不能超过5次访问,WD是scope定义的值,
    
        }
    }
    

    我们可以在postman~~或者DRF自带的页面进行测试都~~可以没什么区别~~   

  • 相关阅读:
    百度之星资格赛1001——找规律——大搬家
    HDU1025——LIS——Constructing Roads In JGShining's Kingdom
    DP(递归打印路径) UVA 662 Fast Food
    递推DP UVA 607 Scheduling Lectures
    递推DP UVA 590 Always on the run
    递推DP UVA 473 Raucous Rockers
    博弈 HDOJ 4371 Alice and Bob
    DFS(深度) hihoCoder挑战赛14 B 赛车
    Codeforces Round #318 [RussianCodeCup Thanks-Round] (Div. 2)
    DP(DAG) UVA 437 The Tower of Babylon
  • 原文地址:https://www.cnblogs.com/wjs521/p/9986610.html
Copyright © 2011-2022 走看看