一、匿名用户IP
**1.使用目的:**为了限制用户(登录/未登录)的访问频率,不让用户频繁的访问网站或网站的某个视图,即节流。
# 节流(控制访问频率)
from rest_framework.throttling import BaseThrottle
class VisitThrottle(object):
"""节流"""
def allow_request(self,request, view):
return True # Flase 表示访问频率太高,被限制
def wait(self):
return None
2.那么如何获取用户的ip来限制用户访问频率呢?(原理)
# 节流(控制访问频率)
from rest_framework.throttling import BaseThrottle
VISIT_RECORD = {} # 这里其实应该放到缓存中, 防止程序重启后清空该字典。
import time
ctime = time.time()
class VisitThrottle(object):
"""节流"""
def __init__(self):
self.history = None
def allow_request(self,request, view):
# 1 获取用户的远程ip
remote_addr = request.META.get('REMOTE_ADDR')
# 2 查看是否有该ip, 如果没有,表示没有访问过,予以访问
if remote_addr not in VISIT_RECORD:
VISIT_RECORD[remote_addr] = [ctime,]
return True
# 3 如果有该ip 获取访问记录
history = VISIT_RECORD.get(remote_addr)
self.history = history
# 4 查看该ip是否过期(60秒内只允许访问3次)
while history and history[-1] < ctime - 60:
history.pop()
if len(history) < 3:
history.insert(0,ctime)
return True
def wait(self):
"""需要等多久才能访问"""
return 60 - (ctime - self.history[-1])
3. 源码
略
4.全局配置
也是在settings中配置,配置方法跟认证和权限一样的。
5.内置控制频率的类使用—使用的时候用这种方式
首先定义一个单独的类(我这里是放在一个单独的文件中)
# 节流(控制访问频率)
from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):
scope = 'throttle_key' # 控制频率,当key用
def get_cache_key(self,request, view):
return self.get_ident(request)
然后在settings文件中配置
REST_FRAMEWORK = {
# 这里写需要的路径,不能写在view中。可以单独建一个文件夹
'DEFAULT_THROTTLE_CLASSES': ['api.utils.throttle.VisitThrottle'], # 全局控制节流
'DEFAULT_THROTTLE_RATES': { # 这里配置节流的访问频率,
"throttle_key": '3/m' # 这里表示每分钟三次
}
}
二、对登录用户使用节流—使用的时候用这种方式
# 登录节流(控制访问频率)
from rest_framework.throttling import SimpleRateThrottle
class UserThrottle(SimpleRateThrottle):
scope = 'user_key' # 控制频率,当key用
def get_cache_key(self,request, view):
return request.user.username # 只需要这里修改即可
然后在settings文件中配置
REST_FRAMEWORK = {
# 如果需要并存,需要写两个不同的节流类来分别实现。并且只能在setting中配置一个,如果需要两个, 可以配置在视图函数中。
'DEFAULT_THROTTLE_CLASSES': ['api.utils.throttle.UserThrottle'], # 全局控制节流
'DEFAULT_THROTTLE_RATES': { # 这里配置节流的访问频率,
# "throttle_key": '3/m' # 这里表示每分钟三次
"user_key": '10/m' # 这里表示每分钟十次
}
}
三、总结
对于访问控制来说,只能一定的程度上来避免频繁的访问,因为对于ip来说,对使用代理是无法控制的,对于登录用户,如果注册账号有很多个,频繁的更换来访问也不能控制。
1、全局
a、基本使用:写一个类,继承SimpleRateThrottle
,只需要实现get_cache_key
并且写一个字段scope
b、在settings中配置好两项
跟认证一样的写法。
2、局部
a、基本使用:写一个类,继承SimpleRateThrottle
,只需要实现get_cache_key
并且写一个字段scope
b、在视图函数中加入throttle_classes = [节流,]