Fork me on GitHub

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')
posted @ 2018-03-01 20:40  派对动物  阅读(318)  评论(0编辑  收藏  举报
Top