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
至此,接口限流器的配置已经完成。