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