千锋扣丁学堂Python培训之django基于中间件实现限制ip频繁访问过程详解

2019-07-30 14:20:08 127浏览

今天千锋扣丁学堂Python培训老师给大家分享一篇关于django基于中间件实现限制ip频繁访问过程详解,首先浏览器前端传来的请求,必须通过中间件,才能到后面路由,视图函数,所以我们在中间件那里做一层处理,我们还需要知道是哪个ip,在什么时候,请求了几次,这些数据是要知道,并且记录下来,所以我创建了一个表,来存放这些信息数据,下面我们一起来看一下吧。



models文件:

class Host_info(models.Model):
 host = models.CharField(max_length=32)
 count = models.IntegerField()
 start_time = models.DateTimeField()
 is_lock = models.CharField(max_length=32,default='2')

host:记录主机ip

count:记录请求的次数

start_time:记录请求的时间

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

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

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

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render, HttpResponse
from app01 import models
import datetime
class Md1(MiddlewareMixin):
 def process_request(self, request):
  url = request.path
  if url.startswith('/favicon.ico'):
   return HttpResponse
class Md2(MiddlewareMixin):
 def process_request(self, request):
  now_time = datetime.datetime.now()
  host = request.META.get('REMOTE_ADDR')
  ret = models.Host_info.objects.filter(host=host).first()
  if ret:
   aa = now_time - ret.start_time
   if aa.seconds >= 60:
    ret.count = 1
    ret.start_time = now_time
    ret.is_lock = '2'
    ret.save()
    return None
   if aa.seconds < 60 and ret.is_lock == '1':
    return HttpResponse('登陆次数频繁,一分钟后再试')
 
   if ret.count < 4 and ret.is_lock == '2':
    if ret.count == 2:
     ret.is_lock = '1'
     ret.count = 0
     ret.save()
    else:
     ret.count += 1
     ret.start_time = now_time
     ret.save()
    return None
  else:
   models.Host_info.objects.create(host=host, start_time=now_time, count=1)
   return None

settings文件:

添加两行代码在MIDDLEWARE列表中:

'mymiddleware.Md1',
'mymiddleware.Md2',

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

TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False

遇到两个问题:

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

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

解决方式:在setting文件中将上面那两句修改为TIME_ZONE='Asia/Shanghai',USE_TZ=False。这样就解决了。

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

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

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

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

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

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

补充一点,datetime的一个用法

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

aa = now_time - ret.start_time
aa.seconds # 取到相差多少秒

这里的aa是datetime.timedelta类型

以上就是关于千锋扣丁学堂Python培训之django基于中间件实现限制ip频繁访问过程详解的全部内容,希望对大家的学习有所帮助,最后想要了解更多关于Python和人工智能方面内容的小伙伴,请关注扣丁学堂Python培训官网、微信等平台,扣丁学堂IT职业在线学习教育平台为您提供权威的Python开发环境搭建视频,Python培训后的前景无限,行业薪资和未来的发展会越来越好的,扣丁学堂老师精心推出的Python视频教程定能让你快速掌握Python从入门到精通开发实战技能。扣丁学堂Python技术交流群:279521237。


扣丁学堂微信公众号                          Python全栈开发爬虫人工智能机器学习数据分析免费公开课直播间


      【关注微信公众号获取更多学习资料】         【扫码进入Python全栈开发免费公开课】



查看更多关于"Python开发资讯"的相关文章>

标签: Python培训 Python视频教程 Python在线视频 Python学习视频 Python培训班

热门专区

暂无热门资讯

课程推荐

微信
微博
15311698296

全国免费咨询热线

邮箱:codingke@1000phone.com

官方群:148715490

北京千锋互联科技有限公司版权所有   北京市海淀区宝盛北里西区28号中关村智诚科创大厦4层
京ICP备12003911号-6   Copyright © 2013 - 2019

京公网安备 11010802030908号