返回顶部

Django实现文件上传、文件列表查看、修改、限流和日志记录7

Django实现文件上传、文件列表查看、修改、限流和日志记录7

不管调用的接口在内网,还是外网都需要做好限制保证接口的访问和限流降级处理,本章节新增限流功能。

限流功能主要针对两个方面: IP和用户

针对IP限流

文件列表接口进行限流处理,限制每分钟每个 IP 访问 10 次,你可以使用 Django 的内置限流功能结合缓存来实现

使用了 Django 的缓存系统来存储每个 IP 地址的访问次数。对于每个请求,我们首先获取客户端的 IP 地址,然后检查该 IP 地址的访问次数。如果访问次数超过限制(10 次),我们返回 403 Forbidden 响应。否则,我们增加访问次数并将缓存时间设置为 1 分钟。

from django.core.cache import cache
from django.http import HttpResponseForbidden

def file_list(request):
    # 获取客户端 IP 地址
    client_ip = request.META.get('REMOTE_ADDR')

    # 检查该 IP 地址的访问次数
    cache_key = f'file_list:{client_ip}'
    access_count = cache.get(cache_key, 0)

    # 如果访问次数超过限制,返回 403 Forbidden
    if access_count >= 10:
        logging.warning('用户 {} 在 {} 访问用户列表超过限制'.format(request.user.username, datetime.now()))
        return HttpResponseForbidden('访问次数超过限制')

    # 增加访问次数并设置缓存时间为 1 分钟
    cache.set(cache_key, access_count + 1, 60)

    # 继续处理文件列表逻辑
    # ...

    return render(request, 'file_list.html', {'file_list': file_list})

 

访问十次提示次数超限

 

针对用户限流

限制每个用户每分钟访问文件列表的次数,你可以使用 Django 的内置限流功能结合缓存来实现。

以下是一个示例代码,演示如何对每个用户进行限流处理,限制每分钟访问文件列表的次数为 10 次:

from django.core.cache import cache
from django.http import HttpResponseForbidden

def file_list(request):
    # 获取当前用户
    user = request.user

    # 检查该用户的访问次数
    cache_key = f'file_list:{user.username}'
    access_count = cache.get(cache_key, 0)

    # 如果访问次数超过限制,返回 403 Forbidden
    if access_count >= 10:
        logging.warning('用户 {} 在 {} 访问用户列表超过限制'.format(request.user.username, datetime.now()))
        return HttpResponseForbidden('访问次数超过限制')

    # 增加访问次数并设置缓存时间为 1 分钟
    cache.set(cache_key, access_count + 1, 60)

    # 继续处理文件列表逻辑
    # ...

    return render(request, 'file_list.html', {'file_list': file_list})

 

访问十次依然提示次数超限

装饰器限流

将限流定义为一个函数,并在其他接口中引用并设置不同的访问次数限制,你可以将限流逻辑封装在一个装饰器函数中,并在需要进行限流的视图函数上应用该装饰器。

#定义限流装饰器
from django.core.cache import cache
from django.http import HttpResponseForbidden

def rate_limit(limit_count):
    def decorator(view_func):
        def wrapper(request, *args, **kwargs):
            # 获取当前用户
            user = request.user

            # 检查该用户的访问次数
            cache_key = f'rate_limit:{user.username}'
            access_count = cache.get(cache_key, 0)

            # 如果访问次数超过限制,返回 403 Forbidden
            if access_count >= limit_count:
                logging.error('用户 {} 在 {} 查看上传文件列表失败'.format(request.user.username, datetime.now()))
                return HttpResponseForbidden('访问次数超过限制')

            # 增加访问次数并设置缓存时间为 1 分钟
            cache.set(cache_key, access_count + 1, 60)

            # 继续执行视图函数
            return view_func(request, *args, **kwargs)

        return wrapper

    return decorator

定义了一个名为 rate_limit 的限流函数,它接受一个访问次数限制作为参数。该函数返回一个装饰器函数,用于包装需要进行限流的视图函数。

要在其他接口上应用限流,你可以使用 @rate_limit(limit_count) 这样的语法,将装饰器应用到视图函数上。

###   调用示例一
#导入装饰器的限流函数
from .views import rate_limit

@rate_limit(10) #设置访问次数限制为10
@login_required
def file_list(request):

###   调用示例二
#导入装饰器的限流函数,若找不到rate_limit模块检查导入文件路径,将限流装饰器放在调用视图前面
from .views import rate_limit

@rate_limit(10) #设置访问次数限制为10
@login_required
def view_file(request, file_name):

访问上述两个路由地址超过十次报错,超过次数限制

 

django-ratelimit库进行限流

RatelimitMiddleware是django-ratelimit库提供的中间件,用于在请求到达视图之前进行请求限流,本次不做使用演示可自行了解使用,以下是一个演示示例:
#在Django的settings.py配置文件中添加以下配置:
# settings.py

INSTALLED_APPS = [
  # ...
  'ratelimit',
  # ...
]

MIDDLEWARE = [
  # ...
  'ratelimit.middleware.RatelimitMiddleware',
  # ...
]

# 在应用限流的视图函数或者类上使用ratelimit装饰器来进行限流设置
# myapp/views.py

from ratelimit.decorators import ratelimit

@ratelimit(key='ip', rate='5/m')  # 设置每分钟每个用户最多5个请求
def my_view(request):
  if request.limited:
        # 请求被限流的处理逻辑
        return HttpResponse('请求过于频繁,请稍后再试', status=429)

  # 处理请求的代码
  pass

 

至此,接口限流器的配置已经完成。

 

posted @ 2023-08-13 17:34  九尾cat  阅读(101)  评论(0编辑  收藏  举报