zoukankan      html  css  js  c++  java
  • Django18-中间件和cache实现限制用户访问频率

    需求:

    同一个源ip访问web时,判断该ip访问的频率,如果1分钟内访问次数超过10次,则锁定1分钟,1分钟后可以再次访问

    通过中间件和cache来实现,在中间件process_request中获取用户的客户端ip,将ip添加到cache中,以该ip为key,时间戳列表为value,{ ip, [] }

    from django.core.cache import cache
    from django.http import HttpResponse
    from django.utils.deprecation import MiddlewareMixin
    
    import time
    
    '''
    限制用户登录频率,1分钟内最多登录10次
    '''
    
    
    class LoginTimesMiddle(MiddlewareMixin):
        def process_request(self, request):
            # ip = request.META.get('REMOTE_ADDR')
            ip = request.META.get('REMOTE_ADDR')
            print(ip)
    
            # 从cache中获取这个ip每次登录的时间戳列表
            req = cache.get(ip, [])
            print(req)
    
            # if req:
            #     # 时间戳从后往前排,最新的时间戳放在最前面,如果用户登录时间与列表中最早的时间差大于1分钟,则删除最早的时间戳
            #     while time.time() - req[-1] > 60:
            #         req.pop()
    
            while req and time.time() - req[-1] > 60:
                req.pop()
    
            # 每次登录都将当前时间戳插入到cache中的ip列表最前面保存,并设置超时时间60秒
            req.insert(0, time.time())
            cache.set(ip, req, timeout=60)
    
            if len(req) > 10:
                return HttpResponse('请求次数过于频繁,请1分钟后尝试')

    如果1分钟内访问次数超过30次,则将该源ip加入黑名单中,24小时内限制访问

    from django.core.cache import cache
    from django.http import HttpResponse
    from django.utils.deprecation import MiddlewareMixin
    
    import time
    
    '''
    限制用户登录频率,1分钟内最多登录10次
    '''
    
    
    class LoginTimesMiddle(MiddlewareMixin):
        def process_request(self, request):
            # ip = request.META.get('REMOTE_ADDR')
            ip = request.META.get('REMOTE_ADDR')
            print(ip)
    
            # 从cache中获取这个ip每次登录的时间戳列表
            req = cache.get(ip, [])
            print(req)
    blacklist_ip
    = cache.get('blacklist',[]) if ip in blacklist_ip: return HttpResponse('ip在黑名单中,禁止访问') # if req: # # 时间戳从后往前排,最新的时间戳放在最前面,如果用户登录时间与列表中最早的时间差大于1分钟,则删除最早的时间戳 # while time.time() - req[-1] > 60: # req.pop() while req and time.time() - req[-1] > 60: req.pop() # 每次登录都将当前时间戳插入到cache中的ip列表最前面保存,并设置超时时间60秒 req.insert(0, time.time()) cache.set(ip, req, timeout=60) if len(req) >= 30: #如果1分钟内访问次数超过30次,则将ip加入黑名单中,24小时内禁止登录 blacklist_ip.append(ip) cache.set('blacklist',blacklist_ip,timeout=60*60*24) return HttpResponse('访问过于频繁,ip被加入黑名单中') if len(req) > 10: return HttpResponse('请求次数过于频繁,请1分钟后尝试')

    注意settings.py中需要注册中间件

    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',
        'devops.middleware.LoginTimesMiddle',
    ]
  • 相关阅读:
    Android Studio 配置快速生成模板代码
    Android开发 AndroidViewModel详解
    adb命令 logcat日志抓取
    Android开发 自定义View_白色圆型涟漪动画View
    Java Queue队列
    Java 几种队列区别的简单说明
    Android开发 retrofit下载与上传
    Android开发 retrofit入门讲解 (RxJava模式)
    Java学习 时间类 Period类与Duration类 / LocalDate类与Instant类 用法详解
    Java 学习 时间格式化(SimpleDateFormat)与历法类(Calendar)用法详解
  • 原文地址:https://www.cnblogs.com/dxnui119/p/14061757.html
Copyright © 2011-2022 走看看