DRF 用户频率限制
DRF 用户频率限制
为什么要限流
1 防爬虫
匿名用户 无法限制,代理
已登录,用户名限制;买代理
2 提供服务(接口--不同用户的访问次数不一样)
vip 限制访问次数
BaseThrottle 自定义 allow_reques,wait t实现用户 ip 访问限制
RECORD = {} # 定义在全局的 记录(记录ip访问)
class MyThrottle(BaseThrottle):
def allow_request(self,request,view):
"""
:param request:
:param view:
:return:
"""
'''
a. 对匿名用户进行限制,每个用户1分钟只允许访问10次
--获取用户IP
'''
import time
ctime = time.time()
ip = self.get_ident(request) # 获取 ip地址
if ip not in RECORD:
RECORD[ip] = [ctime,]
else:
time_list = RECORD[ip]
while True:
first_time = time_list[-1]
if ctime - 60 > first_time:
time_list.pop()
else:
break
if len(time_list) > 10:
return False
time_list.insert(0,ctime)
return True
def wait(self): # 显示剩余时间
ip = self.get_ident()
ip_list = RECORD[ip]
import time
ctime = time.time()
remain_time = 60 - ctime + ip_list[-1]
return remain_time
继承 SimpleRateThrottle -- get_cache_key实现
class MySimpleThrottle(SimpleRateThrottle):
scope = 'WDP' # 配置 'DEFAULT_THROTTLE_RATES':{'WDP':'3/m'}
def get_cache_key(self, request, view):
return self.get_ident(request) # 设置 ip 为 cache记录的 key
settings 中
REST_FRAMEWORK = {
'UNAUTHENTICATED_USER':None,
'UNAUTHENTICATED_TOKEN':None,
# 'DEFAULT_AUTHENTICATION_CLASSES':[
# 'goods.utils.MyAuthentication'
# ],
'DEFAULT_THROTTLE_RATES':{
'WDP':'3/m'
}
}
DRF 的 ip 访问 记录默认放在 cache中,可以通过配置文件 修改缓存方式
返回ip(匿名),或者user(登录)
class AnonyThrottle(SimpleRateThrottle):
scope = 'WDP_ANONNY' # 配置 'DEFAULT_THROTTLE_RATES':{'WDP':'3/m'}
def get_cache_key(self, request, view):
if request.user:
return None
return self.get_ident(request) # 设置 ip 为 cache访问记录的 key
class UserThrottole(SimpleRateThrottle):
scope = 'WDP_USER'
def get_cache_key(self, request, view):
if request.user:
return request.user # 设置 user 为cache访问记录的key
return None
class VIPThrottole(SimpleRateThrottle):
scope = 'WDP_VIP'
def get_cache_key(self, request, view):
if request.user and request.user == 'ale':
return request.user
return None
IP 访问控制的 提示信息
def throttled(self, request, wait):
"""
If request is throttled, determine what kind of exception to raise.
"""
class MyThrottole(exceptions.Throttled):
default_detail = '限制访问.'
extra_detail_singular = '需要再等 {wait} 秒.'
extra_detail_plural = '需要再等 {wait} 秒.'
raise MyThrottole(wait)
获取请求的IP
request.META.get('REMOTE_ADDR')
读书使人心眼明亮