########django-基于中间件写一个限制频繁登陆########
########django-基于中间件写一个限制频繁登陆########
额额,标题已经很醒目了,通过中间件去实现,其他方法也可以实现
浏览器前端传来的请求,必须通过中间件,才能到后面路由,视图函数,所以我们在中间件那里做一层处理,
我们还需要知道是哪个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的状态,默认为2 2代表未锁定,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类型
########django-基于中间件写一个限制频繁登陆########的更多相关文章
- 【Python】如何基于Python写一个TCP反向连接后门
首发安全客 如何基于Python写一个TCP反向连接后门 https://www.anquanke.com/post/id/92401 0x0 介绍 在Linux系统做未授权测试,我们须准备一个安全的 ...
- django写一个简单的登陆注册
要写这个,前提还是需要知道三个知识: 一个是urls.py,它是写我们的路由关系的,之前我写了通过wsgiref写一个简单的服务端,也用到了路由,就是 请求过来的url和视图函数的对应关系. 二是就是 ...
- django基于中间件的IP访问频率控制
一.中间件的代码 注意:成功时返回的是None,那样才会走视图层,返回httpresponse就直接出去了 import time from django.utils.deprecation impo ...
- 初学html,任务2:写一个简单的登陆/注册界面
先在body中把最基础的标签写出来 现在页面运行出来是这样的 就是一个没有任何样式的基础界面: 接下来我们为这些标签加上样式 首先还是让页面所有元素的padding和margin都设置为0, 清除浏览 ...
- 基于Blazor写一个简单的五子棋游戏
写这个五子棋游戏,其实主要目的是想尝试一下微软新作Blazor.Blazor对于那些搞.NET的程序员,又想做一些前端工作,真的挺友好,不用一句JS就可搞定前端交互,美哉.现在已经有很流行的前端框架, ...
- python+selenium+unnitest写一个完整的登陆的验证
import unittest from selenium import webdriver from time import sleep class lonInTest (unittest.Test ...
- 初学Javascript,写一个简易的登陆框
<!--下面是源代码--> <!DOCTYPE html> <html> <head> <meta charset = "utf-8&q ...
- 用Html写一个简单的登陆界面
<!DOCTYPE html> <html> <title>登陆页面</title> <head> <meta charset=&qu ...
- django 和 mongdb 写一个简陋的网址,以及用django内置的分页功能
https://github.com/factsbenchmarks/simple_websit_about_58 一 设置 数据库的设置 在settings文件中加入这样一段代码: from mon ...
随机推荐
- js 做留言提交
如下是留言提交源码 功能:点击按钮或点击enter键可以提交内容扩展:ctrlKey\shiftKey\altKye 可以将如上三个参数与oEvent.keyCode == 13 进行与操作可以得到 ...
- 验证符号文件的又一方法(!itoldyouso)
如果您正在开发软件,很可能遇到了“不匹配的PDB”调试器错误.当您将调试器指向错误的符号路径时,通常会发生这种情况. 但有时你确信你所指向的符号是正确的符号,这让你想知道为什么调试器认为这些符号不匹配 ...
- vlang 试用
vlang 是最近出来的一门编程语言,集成了rust,golang, 等语言的特性,轻量.简洁.编译 快速,详细的比价参数可以参考官方文档 安装 目前尽管官方提供了linux以及mac 的二进制文件, ...
- circus && web comsole docker-compose 独立部署
问题的根本原因是web console 的bug(实际上还是python 对于依赖版本出来不明确) circus 进程docker 镜像 dockerfile FROM python:slim-str ...
- 9-ESP8266 SDK开发基础入门篇--编写串口上位机软件
https://www.cnblogs.com/yangfengwu/p/11087613.html 页面修改成这样子 现在看串口发送数据 点击点亮 发送0xaa 0x55 0 ...
- 15-ESP8266 SDK开发基础入门篇--上位机串口控制 Wi-Fi输出PWM的占空比,调节LED亮度,上位机程序编写
https://www.cnblogs.com/yangfengwu/p/11104167.html 先说一下整体思路哈.. 咱滑动的时候 会进入这个,然后咱呢不直接从这个里面写发送 因为这样的话太快 ...
- 【转】Java 8新特性(四):新的时间和日期API
Java 8另一个新增的重要特性就是引入了新的时间和日期API,它们被包含在java.time包中.借助新的时间和日期API可以以更简洁的方法处理时间和日期. 在介绍本篇文章内容之前,我们先来讨论Ja ...
- kafka 创建消费者报错
kafka-console-consumer.sh --zookeeper master:2181,slave1:2181,slave2:2181 --topic test --from-beginn ...
- 20189220 余超《Linux内核原理与分析》第六周作业
系统调用的三层机制 实验过程 1.克隆MenuOS rm menu -rf //强制删除当前menu git clone http://git.shiyanlou.com/mengning/menu. ...
- 关于证书如何完成身份验证(SSL证书)
一.写在前面 SSL和IPsec是现在VPN技术中最为常见的,在云计算的应用环境中,SSL更受企业青睐,至于原因的话简单的说就是SSL更为简洁,不需要像IPsec那样需要额外安装客户端,这会带来软件维 ...