django基于中间件的IP访问频率控制
一.中间件的代码
注意:成功时返回的是None,那样才会走视图层,返回httpresponse就直接出去了
import time from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse # 访问IP池 visit_ip_pool = {} class RequestBlockingMiddleware(MiddlewareMixin): def process_request(self,request): # 获取访问者IP ip=request.META.get("REMOTE_ADDR") # 获取访问当前时间 visit_time=time.time() # 判断如果访问IP不在池中,就将访问的ip时间插入到对应ip的key值列表,如{"127.0.0.1":[时间1]} if ip not in visit_ip_pool: visit_ip_pool[ip]=[visit_time] return None # 然后在从池中取出时间列表 history_time = visit_ip_pool.get(ip) # 循环判断当前ip的时间列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间, while history_time and visit_time-history_time[-1]>60: history_time.pop() # 如果访问次数小于10次就将访问的ip时间插入到对应ip的key值列表的第一位置,如{"127.0.0.1":[时间2,时间1]} print(history_time) if len(history_time)<10: history_time.insert(0, visit_time) return None else: # 如果大于10次就禁止访问 return HttpResponse("访问过于频繁,还需等待%s秒才能继续访问"%int(60-(visit_time-history_time[-1])))
二.在settings中的配置
这个很简单,一句话搞定
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', # ip访问限制 'blog.middleware.RequestBlockingMiddleware', ]
最后注意:可能你页面的刷新不止一次访问服务端,这个得看你自己的代码了,所以你会错以为怎么限制10次和自己的设定的不一样