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

AnonRateThrottle匿名限流类:继承了SimpleRateThrottle , 重写了 get_cache_key 方法AnonRateThrottle 只会限制未经身份验证的用户 。传入的请求的IP地址用于生成一个唯一的密钥 。允许的请求频率由以下各项之一确定(按优先顺序):

  1. 类的 rate 属性 , 可以通过继承 AnonRateThrottle 并设置该属性来修改这个值 , 优先级高
  2. settings配置文件中 DEFAULT_THROTTLE_RATES['anon'] 配置项的值 。优先级低
  3. anonratetrottle 适用于想限制来自未知用户的请求频率的情况
class AnonRateThrottle(SimpleRateThrottle):# 设置频率控制的key为anonscope = 'anon'# 重写get_cache_key方法def get_cache_key(self, request, view):# 如果请求用户是经过认证的用户 , 不需要进行限流 , 直接返回Noneif request.user.is_authenticated:return None# 如果用户是未经认证的用户 , 将该类的scope和 用户的IP地址传入SimpleRateThrottle的self.cache_format类属性return self.cache_format % {'scope': self.scope,'ident': self.get_ident(request)}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} 自定义限流类上面源码的类 , 我们一般使用的是后三个 , 如果源码提供的限流类无法满足我们的需求 , 我们可以写自定义的限流类自定义限流类的步骤:

经验总结扩展阅读