django基于中间件实现限制ip频繁访问过程详解

  

额额,标题已经很醒目了,通过中间件去实现,其他方法也可以实现

  

浏览器前端传来的请求,必须通过中间件,才能到后面路由,视图函数,所以我们在中间件那里做一层处理,我们还需要知道是哪个ip,在什么时候,请求了几次,这些数据是要知道,并且记录下来,所以我创建了一个表,来存放这些信息数据

  

模型文件:
  

        类Host_info (models.Model):   主机=models.CharField (max_length=32)   数=models.IntegerField ()   start_time=models.DateTimeField ()   is_lock=models.CharField (max_length=32,默认=' 2 ')      

主持人:记录主机ip
  

  

数:记录请求的次数
  

  

start_time:记录请求的时间
  

  

is_lock:记录该ip的状态,默认为2,,2代表未锁定,1代表锁定

  

接下来就是自定义中间件了,并写process_request方法,我们只对请求做处理,我先贴代码,最后写我遇到的一些问题

  

mymiddleware文件(我自定义的中间件):

        从django.utils.deprecation进口MiddlewareMixin   django。快捷方式进口呈现,HttpResponse   从app01导入模型   进口日期时间   类Md1 (MiddlewareMixin):   def process_request(自我,要求):   url=request.path   如果url.startswith ('/ico的位于):   返回HttpResponse   类Md2 (MiddlewareMixin):   def process_request(自我,要求):   now_time=datetime.datetime.now ()   主机=request.META.get (“REMOTE_ADDR”)   ret=models.Host_info.objects.filter(主机=主机)当代()   如果延迟:   aa=now_time - ret.start_time   如果aa。秒祝辞=60:   ret.count=1   ret.start_time=now_time   ret.is_lock=' 2 '   ret.save ()   回来没有   如果aa。秒& lt;60和ret.is_lock==' 1 ':   返回HttpResponse(“登陆次数频繁,一分钟后再试”)      如果ret.count & lt;4和ret.is_lock==?”:   如果ret.count==2:   ret.is_lock=' 1 '   ret.count=0   ret.save ()   其他:   ret.count +=1   ret.start_time=now_time   ret.save ()   回来没有   其他:   models.Host_info.objects。创建(主机=主机,start_time=now_time数=1)   返回所有      

设置文件:
  

  

添加两行代码在中间件列表中:
  

        “mymiddleware.Md1”,   “mymiddleware.Md2”,      

并配置下面两句,原因后面会说
  

        TIME_ZONE='亚洲/上海'   USE_TZ=False      

遇到两个问题:

  

<强>问题一:就是datetime,也就是时间分区问题,因为我数据表中需要保存到该ip访问的时间,存的时候存的是datetime对象,但是我从数据库中取出来这个时间,进行比较会报出错误,错误类型忘记了,我就打印了从数据库中取出的时间数据,,发现,这个时间带着时区,而我datetime.datetime.now()的时间是本机时间,根本不能相减,相比较。

  

网上收索才,知道django默认是有时间分区的,TIME_ZONE=UTC, USE_TZ=True,这两句。
  

  

<>强解决方式:在设置文件中将上面那两句修改为TIME_ZONE=把侵?上海”,USE_TZ=False。这样就解决了。
  

  

在django中但凡出现时间的话,这个地方需要注意下。

  

<强>问题二:额额这个问题,我在写的时候出现过,但是今天测试没那个问题,反正写上吧。我之前的错误就是我发出一个请求,

  

首先
  

  

第一个请求就是访问到url,接着第二个请求就是发出的图标。ico图标这种类似的,请求这个。以这个情况来说问题吧,
  

  

你虽然在浏览器只发出一个请求,但是响应过来的网页,里面可以还有其他请求,所以这中情况需要考虑到。

  

<>强解决方式:我在对用户ip做限制之前,加一个中间件,过滤掉其它的请求,也就是上面的MD1。

        # #代码其实很简单,主要是逻辑处理,你是怎么想就用代码去实现。   # #对了,这里的数据存储,你可以定义一个变量去存放存这些信息(也就是我数据表存放的这个)   # #这里唯一值得注意的就是时间了,你要很清楚知道时区这个问题。      

补充一点,datetime的一个用法
  

  

例子中我用到datetime对象之间相减,取差多少秒,也就是这句
  

     

django基于中间件实现限制ip频繁访问过程详解