drf 三大认证之 频率组件

源码相关:
   
# 1)APIView的dispath方法中的 self.initial(request, *args, **kwargs) 点进去
# 2)self.check_throttles(request) 进行频率认证

# 频率组件核心源码分析
def check_throttles(self, request):
    throttle_durations = []
    # 1)遍历配置的频率认证类,初始化得到一个个频率认证类对象(会调用频率认证类的 __init__() 方法)
    # 2)频率认证类对象调用 allow_request 方法,判断是否限次(没有限次可访问,限次不可访问)
    # 3)频率认证类对象在限次后,调用 wait 方法,获取还需等待多长时间可以进行下一次访问
    # 注:频率认证类都是继承 SimpleRateThrottle 类
    for throttle in self.get_throttles():
        if not throttle.allow_request(request, self):
            # 只要频率限制了,allow_request 返回False了,才会调用wait
            throttle_durations.append(throttle.wait())

            if throttle_durations:
                # Filter out `None` values which may happen in case of config / rate
                # changes, see #1438
                durations = [
                    duration for duration in throttle_durations
                    if duration is not None
                ]

                duration = max(durations, default=None)
                self.throttled(request, duration)
 1 自定义频率类:
 2 
 3 指路实现:
 4 
 5  1) 自定义一个继承 SimpleRateThrottle 类 的频率类
 6  2) 设置一个 scope 类属性,属性值为任意见名知意的字符串
 7  3) 在settings配置文件中,配置drf的DEFAULT_THROTTLE_RATES,格式为 {scope字符串: '次数/时间'}
 8  4) 在自定义频率类中重写 get_cache_key 方法
 9     # 限制的对象返回 与限制信息有关的字符串
10     # 不限制的对象返回 None (只能放回None,不能是False或是''等)
11 
12 eg:短信接口 1/min 频率限制
13 
14 from rest_framework.throttling import SimpleRateThrottle
15 
16 class SMSRateThrottle(SimpleRateThrottle):
17     scope = 'sms'
18 
19     # 只对提交手机号的get方法进行限制
20     def get_cache_key(self, request, view):
21         mobile = request.query_params.get('mobile')
22         # 没有手机号,就不做频率限制
23         if not mobile:
24             return None
25         # 返回可以根据手机号动态变化,且不易重复的字符串,作为操作缓存的key
26         return 'throttle_%(scope)s_%(ident)s' % {'scope': self.scope, 'ident': mobile}
27 
28 
29 
30 drf配置
31 REST_FRAMEWORK = {
32     # 频率限制条件配置
33     'DEFAULT_THROTTLE_RATES': {
34         'sms': '1/min'
35     },
36 }
37 
38 views
39 from .throttles import SMSRateThrottle
40 class TestSMSAPIView(APIView):
41     # 局部配置频率认证
42     throttle_classes = [SMSRateThrottle]
43     def get(self, request, *args, **kwargs):
44         return APIResponse(0, 'get 获取验证码 OK')
45     def post(self, request, *args, **kwargs):
46         return APIResponse(0, 'post 获取验证码  OK')
47 
48 路由配置
49 url(r'^sms/$', views.TestSMSAPIView.as_view()),




原文地址:https://www.cnblogs.com/wyf20190411-/p/13686976.html