Flask-Limiter詳細使用説明

5274 ワード

本論文は行者AIに先発した.
レート制限は通常、サービスの防御措置として実施される.サービスは、意図的であれ意図的であれ、意図的であれ、意図的であれ、サービスの可用性を維持するために、自身を保護する必要があります.Flaskプロジェクトの開発過程で、インタフェースを制限する必要があり、車輪を作りたくないというニーズに遭遇した場合、Flask-Limiterという3つのライブラリを使用する必要があります.ここではFlask-Limiterの使用について詳しく説明します.

1.インストール


依存環境をインストールします.
pip install Flask==1.1.1 Flask-Limiter==1.4

2.クイックスタート


レート制限を表すには、次の2つの方法があります.
  • "100 per day"、"20 per hour"、"5 per minute"、"1 per second"
  • "100/day"、"20/hour"、"5/minute"、"1/second"

  • レート制限は、すべてのインタフェースに対して制限されるグローバル構成を設定できます.装飾器によって局所的な制限を行うこともできる.制限したくないインターフェースについては、デコレーション@limiter.exemptによって制限を解除することができる.サンプルコードは次のとおりです.
    app = Flask(__name__)
    
    #         、       
    limiter = Limiter(app, key_func=get_remote_address, default_limits=["100 per day", "10/hour"])
    
    # @limiter.limit:      limiter  
    @app.route("/slow")
    @limiter.limit("1 per day")
    def slow():
        return ":("
    
    # override_defaults:    limiter      limiter  ,   True
    @app.route("/medium")
    @limiter.limit("1/second", override_defaults=False)
    def medium():
        return ":|"
    
    #       limiter  
    @app.route("/fast")
    def fast():
        return ":)"
    
    # @limiter.exempt:               
    @app.route("/ping")
    @limiter.exempt
    def ping():
        return "PONG"

    3.装飾器


    個々の好みと使用シーンに応じて、単一の修飾:制限文字列は単一の制限であってもよいし、デリミタで区切られた文字列であってもよい.
    @app.route("....")
    @limiter.limit("100/day;10/hour;1/minute")
    def my_route()
      ...

    複数のアクセラレータ:制限文字列は、単一の制限であってもよいし、デリミタで区切られた文字列であってもよいし、両者の組合せであってもよい.
    @app.route("....")
    @limiter.limit("100/day")
    @limiter.limit("10/hour")
    @limiter.limit("1/minute")
    def my_route():
      ...

    ≪カスタム機能|Customize Feature|oem_src≫:デフォルトでは、Limiterインスタンスの初期化時に使用されるキー機能に基づいてレート制限が適用されます.開発者は自分の機能を実現することができる.
    def my_key_func():
      ...
    
    @app.route("...")
    @limiter.limit("100/day", my_key_func)
    def my_route():
      ...

    動的ロード制限の文字列:場合によっては、コード外部のソース(データベース、リモートapiなど)からレート制限を取得する必要があります.これは、アクセラレータに呼び出し可能なオブジェクトを提供することによって実現することができる.
    注:装飾されたルーティングでは、各リクエストが提供される呼び出し可能なオブジェクトを呼び出します.高価な取得の場合は、キャッシュ応答を考慮してください.
    def rate_limit_from_config():
        return current_app.config.get("CUSTOM_LIMIT", "10/s")
    
    @app.route("...")
    @limiter.limit(rate_limit_from_config)
    def my_route():
        ...

    4.制限ドメイン


    何に基づいて制限するかを指し、対応するパラメータはkey_funcflask_limiter.utilの2つの方法を提供する.
  • flask_limiter.util.get_ipaddr():X-Forwarded-Forヘッダーの最後のIPアドレスを使用します.そうしないと、要求されたremote_addressに戻ります.
  • flask_limiter.util.get_remote_address():使用要求のremote_address.

  • 注意:実際の開発では、ほとんどのプロジェクトがNginxを構成しており、get_を直接使用する場合はremote_addressは、取得したのはNginxサーバのアドレスであり、そのNginxサーバからのすべてのリクエストが同じIPアクセスとして扱われることに相当するので、プロジェクトでは一般的にカスタムkey_func!
    def limit_key_func():
        return str(flask_request.headers.get("X-Forwarded-For", '127.0.0.1'))

    IPを取得する根拠は、Nginxの構成によって決定される.
    X-Forwarded-For #                         ip     X-Forwarded-For   ,        ;
    X-Real-IP #             ip        ;
    X-Forwarded-For #    ip  , X-Real-IP   ;
    #         ,           。

    5.共有制限


    レート制限が複数のルーティングで共有される場合に適用されます.
    名前付き共有制限:同じshared_でlimitオブジェクトを装飾します.
    mysql_limit = limiter.shared_limit("100/hour", scope="mysql")
    
    @app.route("..")
    @mysql_limit
    def r1():
       ...
    
    @app.route("..")
    @mysql_limit
    def r2():
       ...

    ≪動的共有制限|Dynamic Shared Limit|oem_src≫:呼び出し可能なオブジェクトを範囲として渡し、その関数の戻り値を範囲として使用します.なお、callableには、リクエストのエンドポイントを表す文字列というパラメータがあります.
    def host_scope(endpoint_name):
        return request.host
    host_limit = limiter.shared_limit("100/hour", scope=host_scope)
    
    @app.route("..")
    @host_limit
    def r1():
       ...
    
    @app.route("..")
    @host_limit
    def r2():
       ...

    6.格納バックエンド


    IPアクセス回数を記録し、そのIPアクセス回数が制限に達したか否かを判断する.Limiterはデフォルトでメモリをストレージバックエンドとして使用していますが、実際の開発では、マルチプロセスリソースが共有されていない、サーバのメモリ消費などの問題が発生する可能性があります.一般的にredisをストレージバックエンドとして使用します.
  • は、redisサーバの場所と、オプションのデータベース番号を必要とします.redis://localhost:6379またはredis://localhost:6379/n(データベースnの場合).
  • redisサーバがunixドメインソケットで傍受している場合、redis+unix:///path/to/sockまたはredis+unix:///path/to/socket?db=n(データベースnの場合)を使用できます.
  • データベースがパスワードによって保護されている場合、URLにパスワード、例えばredis://:foobared@localhost:6379またはredis+unix//:foobered/path/to/socketを提供することができる.
  • # LIMITS_REDIS_STORAGE       redis URI
    limiter = Limiter(default_limits=["100 per day"], key_func=limit_key_func, storage_uri=LIMITS_REDIS_STORAGE)

    7.まとめ


    APIリクエストの制限と割当により、システムがその処理能力を超えるデータを受信することをある程度回避し、システムのリソースが合理的に使用されることを確保することができる.以上が本文のすべての内容で、みんなの学習に助けをもたらすことを望みます.