前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >再谈《Django 限制访问频率》

再谈《Django 限制访问频率》

作者头像
obaby
发布2023-02-24 15:34:09
9560
发布2023-02-24 15:34:09
举报
文章被收录于专栏:obaby@mars

之前提到使用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': '大侠喝口茶,小女子给你讲个故事如何?\r\n 从前有座山,山上有座庙……',
                }
                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/%e5%86%8d%e8%b0%88%e3%80%8adjango-%e9%99%90%e5%88%b6%e8%ae%bf%e9%97%ae%e9%a2%91%e7%8e%87%e3%80%8b/

* 转载文章请标明文章来源,原文标题以及原文链接。请遵从 《署名-非商业性使用-相同方式共享 2.5 中国大陆 (CC BY-NC-SA 2.5 CN) 》许可协议。


分享文章:

相关文章:

  1. Django 限制访问频率
  2. django raw_id_fields 显示名称而不是id(raw_id_fields: How to show a name instead of id)
  3. Django input value值被截断
  4. Django APScheduler + uwsgi 定时任务重复运行
  5. Django REST framework foreignkey 序列化
  6. Django admin Foreignkey ManyToMany list_display展示
  7. django 主动抛出 403 异常
  8. ngix+uwsgi+django 以及阿里云rds数据库数据导入
  9. ubuntu uwsgi No module named ‘django’
  10. Apache2 Django {“detail”:”Authentication credentials were not provided.”}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020年1月17日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 相关文章:
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档