访问频率控制(节流、接口防刷)
* 需求: 判断某个用户访问频率做个控制,比如1分钟只能访问3次,超过次数后我们需要在页面上做一个提示,还有多少秒以后可以访问
*
思路: 我们可以用一个字典来存访问记录,使用用户的IP作为我们的键,值列表,存放每一次访问的时间
使用
可以在配置文件中,使用DEFAULT_THROTTLE_CLASSES 和 DEFAULT_THROTTLE_RATES进行全局配置,
REST_FRAMEWORK = {
‘DEFAULT_THROTTLE_CLASSES’: (
‘rest_framework.throttling.AnonRateThrottle’,
‘rest_framework.throttling.UserRateThrottle’
),
‘DEFAULT_THROTTLE_RATES’: {
‘anon’: ‘10/m’,
‘user’: ‘10/m’
}
}
DEFAULT_THROTTLE_RATES 可以使用 second, minute, hour 或day来指明周期。
也可以在具体视图中通过throttle_classess属性来配置,如
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView
class ExampleView(APIView):
throttle_classes = (UserRateThrottle,)
…
可选限流类
1) AnonRateThrottle
限制所有匿名未认证用户,使用IP区分用户。
使用DEFAULT_THROTTLE_RATES[‘anon’] 来设置频次
2)UserRateThrottle
限制认证用户,使用User id 来区分。
使用DEFAULT_THROTTLE_RATES[‘user’] 来设置频次
3)ScopedRateThrottle
限制用户对于每个视图的访问频次,使用ip或user id。
“”"
class ContactListView(APIView):
throttle_scope = ‘contacts’
class ContactDetailView(APIView):
throttle_scope = ‘contacts’
class UploadView(APIView):
throttle_scope = ‘uploads’
REST_FRAMEWORK = {
‘DEFAULT_THROTTLE_CLASSES’: (
‘rest_framework.throttling.ScopedRateThrottle’,
),
‘DEFAULT_THROTTLE_RATES’: {
‘contacts’: ‘10/m’
‘uploads’: ‘20/m’
}
}
“”"
实例
#节流:
“”"
VISIT_RECORD = {}
class VisitThrottle(object):
def __init__(self):
self.history = None
def allow_request(self,request,view):
#实现节流的逻辑
#基于ip做节流
# #获取用户访问的IP地址
# ip_address = request._request.META.get('REMOTE_ADDR')
ctime = time.time()
# if ip_address not in VISIT_RECORD:
# #第一次访问的时候将访问的时间存储在字典中(ip地址为Key,访问的时间为value值)
# VISIT_RECORD[ip_address] = [ctime,]
#
# #第二次访问的时候取出访问的历史记录
# history = VISIT_RECORD[ip_address]
# 基于用户的节流
username = request.user.username
if username not in VISIT_RECORD:
VISIT_RECORD[username] = [ctime, ]
history = VISIT_RECORD[username]
self.history = history
while history and history[-1] < ctime - 10:
#如果访问的时间记录超过60秒,就把超过60秒的时间记录移除
history.pop()
if len(history) < 6:
history.insert(0,ctime)
return True
return False
def wait(self):
#一旦用户访问次数到达阀值,显示用户需要等待的时间
ctime = time.time()
#09:54:30 09:54:28
return 10 - (ctime - self.history[-1])
“”"
局部使用
“”"
class OrderView(APIView):
# throttle_classes设置节流类
throttle_classes = [VisitThrottle,]
“”"
#全局设置
“”"
REST_FRAMEWORK = {
‘DEFAULT_THROTTLE_CLASSES’:[‘unitls.throttle.VisitThrottle’],
}
“”"
#使用DRF内置的限频类
“”"
from rest_framework.throttling import SimpleRateThrottle
#推荐使用这种
class VisitThrottle(SimpleRateThrottle):
#没有登录用户,每分钟访问10次
scope = 'logined'
def get_cache_key(self, request, view):
return request.user.username
"""