flask使用redis对请求ip与设备进行限制

需求:对客户端ip与设备进行访问控制

有这么一个需求,需要对flask的接口进行限制。同一ip下只允许固定数量的设备进行访问。

1 方法:

  • 使用flask_limiter,缺点只能对ip进行访问频率和次数的控制,无法与设备进行绑定。参考链接:flask_limiter

  • 使用缓存来设置,redis

  • 这里使用redis来实现对ip和设备进行绑定来时先

2 实现:

flask自有的功能:

  • before_request :在请求收到之前绑定一个函数做一些事情。
  • after_request: 每一个请求之后绑定一个函数,如果请求没有异常。
  • teardown_request: 每一个请求之后绑定一个函数,即使遇到了异常。
    这里使用before_request进行所有接口的全局设置:
# before_request类似于装饰器,可以自西, 这里使用自带的,比较方便
# @app.before_request, 可以在单个蓝图中局部使用,也可以使用全局app来实现
@app.before_request
def check_remote_ip_and_device_id():
    # print(request.headers)
    remote_address = request.remote_addr
    device_id = request.headers.get('device-id', None)
    if not device_id:
        return jsonify({"code": 40002, "message": "Not Found Device_id"})
    if device_id == '*':
        return
    ip_index = "{}:{}"
    ret = redis_client.set(name=ip_index.format(remote_address, device_id), value=1, ex=1800, xx=True)  # 存在则更新返回True, 不存在返回None
    if not ret:
        ip_device_obj = redis_client.scan(cursor=0, match=remote_address+':*', count=1000)
        if ip_device_obj[1]:
            if len(ip_device_obj[1]) >= 10:
                return jsonify({"code": 40001, "message": "请切换网络"})
            else:
                redis_client.set(name=ip_index.format(remote_address, device_id), value=1,  nx=True, ex=1800)
        else:
            redis_client.set(name=ip_index.format(remote_address, device_id), value=1, nx=True, ex=1800)
    return

说明
redis只能对最外层的keys进行有效期设置,例如:hash、set、list灯类型的数据,不能对其中的成员单独设置有效期

你可能感兴趣的:(flask,python,flask,redis)