45.限流Throttling及源码解析( 三 )

UserRateThrottle认证用户限流类:继承了SimpleRateThrottle,仅仅是重写了 get_cache_key 方法UserRateThrottle 用于限制已认证的用户在整个API中的请求频率 。用户ID用于生成唯一的密钥 。未经身份验证的请求将使用传入的请求的IP地址生成一个唯一的密钥允许的请求频率由以下各项之一确定(按优先顺序):

  1. 类的 rate 属性,可以通过继承 UserRateThrottle 并设置该属性来修改这个值,优先级高
  2. settings配置文件中 DEFAULT_THROTTLE_RATES['user'] 配置项的值 。优先级低
# 设置频率控制的key位anonscope = 'user'# 重写get_cache_key方法def get_cache_key(self, request, view):if request.user.is_authenticated:# 如果请求用户是认证用户,设置用户的唯一标识赋值给identident = request.user.pkelse:#如果请求用户是非认证用户 , 通过get_ident获取请求ip赋值给identident = self.get_ident(request)# 设置SimpleRateThrottle中self.cache_format的值return self.cache_format % {'scope': self.scope,'ident': ident}ScopedRateThrottle用户对于每个视图的访问频次:继承了SimpleRateThrottle , 重写了 get_cache_key 和allow_request 方法ScopedRateThrottle 类用于限制对APIs特定部分的访问,也就是视图级别的限流,不是全局性的只有当正在访问的视图包含 throttle_scope 属性时 , 才会应用此限制 。然后,通过将视图的“scope”属性值与唯一的用户ID或IP地址连接,生成唯一的密钥 。允许的请求频率由 scope 属性的值在 DEFAULT_THROTTLE_RATES 中的设置确定class ScopedRateThrottle(SimpleRateThrottle):scope_attr = 'throttle_scope'def __init__(self):passdef allow_request(self, request, view):#从view获取self.scope_attr赋值给scope , 如果view中没有指定,设置为Noneself.scope = getattr(view, self.scope_attr, None)# 如果没有设置scope,直接返回Trueif not self.scope:return True# 获取settings频率设置限流类对应的keyself.rate = self.get_rate()# 获取频率限制、持续时长self.num_requests, self.duration = self.parse_rate(self.rate)# 调用父类的allow_request 返回对应的结果return super().allow_request(request, view)# 获取用户唯一标识def get_cache_key(self, request, view):# 如果是认证用户 ident=用户唯一标识if request.user.is_authenticated:ident = request.user.pkelse:# 非认证用户返回请求的ipident = self.get_ident(request)# 设置父类的类属性return self.cache_format % {'scope': self.scope,'ident': ident} 自定义限流类上面源码的类,我们一般使用的是后三个,如果源码提供的限流类无法满足我们的需求,我们可以写自定义的限流类自定义限流类的步骤:
  1. 继承BaseThrottle类或者根据场景继承其他限流类
  2. 实现allow_request方法,如果请求被允许,那么返回True,否则返回False
  3. wait方法,是否实现根据自己场景
  4. 获取唯一标识的方法可以使用源码自由的,也可以自定义
  场景案例1假设我们的请求需要同时进行多个认证用户的限流措施,比如每小时限制100次,同时每天限制1000次# 每小时的限流类class UserHourRateThrottle(UserRateThrottle):scope = 'userHour'# 每天的限流类class UserDayRateThrottle(UserRateThrottle):scope = 'userDay' # settings中进行配置REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': (# 配置我们自定义的限流类或者再view中进行局部的配置'testApi.throttles.UserHourRateThrottle','testApi.throttles.UserDayRateThrottle'),'DEFAULT_THROTTLE_RATES': {'userHour': '100/hour', # 每小时最多100次'userDay': '1000/day' # 每天最多100次}}场景案例2随机限制import randomclass RandomRateThrottle(throttling.BaseThrottle):def allow_request(self, request, view):# 如果随机的数字 不等于1,返回True,否则返回Falsereturn random.randint(1, 10) != 1# 之后在settings进行配置或者局部配置
45.限流Throttling及源码解析

文章插图
【45.限流Throttling及源码解析】

推荐阅读