当前位置 博文首页 > DRF之访问权限控制和访问频率控制(节流)

    DRF之访问权限控制和访问频率控制(节流)

    作者:wushengCN 时间:2021-01-06 15:01

    权限控制

    前言

    用户验证用户权限,根据不同访问权限控制对不同内容的访问。

    建议了解视图、token验证的内容。

    使用流程

    1. 自定义访问权限类,继承BasePermission,重写has_permission()方法,如果权限通过,就返回True,不通过就返回Falsehas_permission()方法接受两个参数,分别是requestview,也就是视图类的实例化本身。

    image-20210106113656701

    1. 配置。

    局部配置:

    permission_classes = [MyUserPermission]
    

    全局配置:

    REST_FRAMEWORK={
        'DEFAULT_PERMISSION_CLASSES': ['libs.MyAuth.UserPermission',],
    }
    

    示例

    class SVIPPermission(BasePermission):   # 推荐继承BasePermission类
        # message = 'You do not have permission to perform this action.'#默认值
        message = '无此权限!!!'
    
        def has_permission(self, request, view):
            if request.user.user_type == 3:
                return False    # False为没权限
            # view.queryset =   # 可以使用这种方式控制视图中要处理的数据(根据不同权限)
            return True         # True为有权限
    

    源码分析

    进入dispatch函数,查看initial方法(执行三大验证)中的check_permissions方法:

    image-20201230163053258

    self.check_permissions(request)将会根据request中的用户内容进行权限控制。

    image-20201230163450342

    image-20201230163538055

    image-20210106113841241

    由上可知,permission_classes要么读取配置文件中的DEFAULT_PERMISSION_CLASSES(全局),要么就在视图类中直接对permission_classes赋值(局部)。

    节流限制

    前言

    控制网站访问频率。

    使用流程

    1. 自定义限制类,继承BaseThrottle
    2. 指定从配置文件中要读取的scope(key),形式为scope="key"

    全局配置:

    REST_FRAMEWORK = {
        'DEFAULT_THROTTLE_CLASSES': [
            'rest_framework.throttling.AnonRateThrottle',
            'rest_framework.throttling.UserRateThrottle'
        ],
        'DEFAULT_THROTTLE_RATES': {
            'anon': '100/day',
            'user': '1000/day'
        }
    }
    

    局部配置:

    throttle_classes = [UserRateThrottle]
    

    就比如UserRateThrottle,继承了SimpleRateThrottle,指定了它所限制的scope,重写了get_cache_key方法。

    image-20210106115349546

    源码分析

    APIViewinitial方法中,三大验证还剩下最后一个没有分析,那就是访问频率验证,如下图:

    image-20210106115306589

    接下来让我们查看check_throttles,可以看到,验证访问频率的时候,调用的方法为频率验证类的allow_request方法。

    image-20210106122326700

    其中get_throttles用的还是老套路:

    image-20210106122353228

    示例

    自定义一个频率限制类:

    from rest_framework.throttling import BaseThrottle
    import time
     
    # 存放访问记录(一般放数据库或者缓存中)
    VISIT_RECORD = {}
     
    class VisitThrottle(BaseThrottle):
     
        def __init__(self):
            self.history = None
     
        def allow_request(self, request, view):
            # 1. 获取用户ip
            remote_addr = request.META.get("REMOTE_ADDR")
    
            # 2. 添加到访问记录中
            ctime = time.time()
            
            # 当VISIT_RECORD中没有这个记录,可以直接访问,添加一个记录
            if remote_addr not in VISIT_RECORD:
                VISIT_RECORD[remote_addr] = [ctime, ]
                return True
            
            history = VISIT_RECORD.get(remote_addr)
            self.history = history
            
            # 拿到最后历史记录里面的最后一个时间,如果最后一个时间小于当前时间-60(一分钟之前的记录)
            while history and history[-1] < ctime - 60:
                history.pop()
            
            if len(history) < 3:	# 允许
                history.insert(0, ctime)
                return True
     
            return False  # False表示访问频率太高被限制
     
        def wait(self):
            """
            还需要等多少秒可以访问
            :return:
            """
            ctime = time.time()
            return 60 - (ctime - self.history[-1])
    

    注意:官方内置的 SimpleRateThrottle 类中对scope的处理值得一看。

    下一篇:没有了