之前提到使用ratelimit来限制访问频率,我的目的是根据用户来限制访问频率,但是实际上通过下面的代码并没有达到效果,如果用多个浏览器进行同时刷新,会存在跳过限制的情况
代码语言:javascript复制@ratelimit(key='user', rate='1/8s', block=True, method=('POST'))
本来是不想重复造轮子的,但是由于这个轮子不大好用,于是只好重新造一个,基于redis可以使用下面的代码来实现(ttl为限制时长):
代码语言:javascript复制def set_method_limit(method_name, player_id, ttl):
cash_name = 'RATELIMIT::METHOD=' method_name 'PLAYERID=' str(player_id)
cache.set(cash_name, method_name, ttl)
def check_is_limit(method_name, player_id):
cash_name = 'RATELIMIT::METHOD=' method_name 'PLAYERID=' str(player_id)
if cash_name in cache:
return True
return False
def redis_ratelimit(method='ALL', block=False, ttl=5):
def decorator(fn):
@wraps(fn)
def _wrapped(*args, **kw):
# Work as a CBV method decorator.
request = args[0]
auth = request.META.get('HTTP_AUTHORIZATION', 'UNKNOWN')
# 获取用户id 如果失败则用token
try:
auth = request.user.id
print('PID= ' str(auth))
except:
pass
token = str(auth).split(' ')[-1]
if check_is_limit(method, token) and block:
content = {
'status': 403,
'message': '大侠喝口茶,小女子给你讲个故事如何?rn 从前有座山,山上有座庙……',
}
return JsonResponse(content)
# raise Redis_Rate_Limit()
set_method_limit(method, token, ttl)
return fn(*args, **kw)
return _wrapped
return decorator
使用方法和retalimit一致:
代码语言:javascript复制@api_view(['POST', 'GET'])
@redis_ratelimit(method='api_test', block=True, ttl=10)
@csrf_exempt
def api_test(request):
"""
测试接口
http://192.168.1.195:8006/rest-api/battle/api-test/
:return: 普通数据测试
"""
return json_response_message(status=API_SUCCESS, message=timezone.now().date())
redis 安装:
代码语言:javascript复制pip3 install django-redis
redis 配置:
代码语言:javascript复制# redis配置
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100}
# "PASSWORD": "密码",
}
}
}
☆文章版权声明☆
* 网站名称:obaby@mars
* 网址:https://h4ck.org.cn/
* 本文标题: 《再谈《Django 限制访问频率》》
* 本文链接:https://h4ck.org.cn/2020/01/再谈《django-限制访问频率》/
* 转载文章请标明文章来源,原文标题以及原文链接。请遵从 《署名-非商业性使用-相同方式共享 2.5 中国大陆 (CC BY-NC-SA 2.5 CN) 》许可协议。
分享文章:
相关文章:
- Django 限制访问频率
- django raw_id_fields 显示名称而不是id(raw_id_fields: How to show a name instead of id)
- Django input value值被截断
- Django APScheduler uwsgi 定时任务重复运行
- Django REST framework foreignkey 序列化
- Django admin Foreignkey ManyToMany list_display展示
- django 主动抛出 403 异常
- ngix uwsgi django 以及阿里云rds数据库数据导入
- ubuntu uwsgi No module named ‘django’
- Apache2 Django {“detail”:”Authentication credentials were not provided.”}