FastAPIを使用してクライアントのIPをログに記録する方法

FastAPIとは

FastAPIは、Pythonの非常に高速な(高性能)、使いやすい、モダンな、高速(高性能)なWebフレームワークです。これは、Python 3.6以降の型ヒントに基づいています。

FastAPIの主な特徴は次のとおりです:

  • 高速: NodeJSやGoと同等の非常に高速なパフォーマンス(StarletteとPydanticのおかげです)。
  • 高速なコーディング: 開発者の生産性を約2倍から3倍に向上させます。開発スピードと、バグやエラーを減らすことで、メンテナンス時間も大幅に削減します。
  • 少ないバグ: システムが自動的に多くのエラーを防ぐため、バグが少なくなります。
  • 直感的: 優れたエディタのサポートと自動補完のおかげで、コードは非常に理解しやすくなります。
  • 簡単: 高度な機能を使い始めるための学習曲線が非常に低いです。
  • 短い: コードの重複を最小限に抑え、複数の機能を直感的に提供します。これにより、バグが少なくなります。
  • 堅牢: プロダクションでの使用を目的として設計されています。
  • スタンダードベース: APIの定義にOpenAPI(以前はSwaggerとして知られていました)とJSON Schemaを使用し、自動的に対話型APIドキュメンテーションとユーザーインターフェースを生成します。
  • JSON対応: JSONリクエストの自動リクエストボディの解析、モデルの変換(デシリアライゼーション)、直接データの変換、データの検証、自動的なエラーレスポンスなど、JSONとの統合が深いです。
  • データクラス対応: モデルの属性とその型を宣言するためのPython 3.6の型ヒントを使用します。これにより、エディタのサポートが向上し、エラーが少なくなります。

以上がFastAPIの概要です。これらの特徴により、FastAPIは現代のWebアプリケーションやマイクロサービスの開発に非常に適しています。次のセクションでは、FastAPIを使用してクライアントのIPをログに記録する方法について詳しく説明します。お楽しみに!

クライアントのIPを取得する基本的な方法

FastAPIを使用してクライアントのIPアドレスを取得する基本的な方法は、リクエストオブジェクトから直接取得することです。以下にその方法を示します。

from fastapi import FastAPI, Request

app = FastAPI()

@app.get("/get_my_ip")
async def get_my_ip(request: Request):
    client_host = request.client.host
    return {"client_host": client_host}

このコードでは、FastAPIのルーティング関数内でRequestオブジェクトを引数として受け取ります。Requestオブジェクトには、クライアントのIPアドレスを含むクライアントに関する情報が含まれています。この情報はrequest.client.hostを通じてアクセスできます。

この方法は、クライアントが直接あなたのアプリケーションに接続している場合にのみ機能します。クライアントがプロキシを介して接続している場合(これは現代のWebアプリケーションでは非常に一般的です)、この方法では正確なクライアントのIPアドレスを取得できません。次のセクションでは、プロキシを介したリクエストの場合のIP取得について説明します。お楽しみに!

プロキシを介したリクエストの場合のIP取得

クライアントがプロキシを介してあなたのアプリケーションに接続している場合、request.client.hostはプロキシのIPアドレスを返します。これは、クライアントの実際のIPアドレスではありません。しかし、多くのプロキシは、元のクライアントのIPアドレスを含むX-Forwarded-ForというHTTPヘッダーを設定します。このヘッダーを使用して、クライアントの実際のIPアドレスを取得することができます。

以下にその方法を示します。

from fastapi import FastAPI, Request
from typing import Optional

app = FastAPI()

@app.get("/get_my_ip")
async def get_my_ip(request: Request):
    x_forwarded_for: Optional[str] = request.headers.get("X-Forwarded-For")
    if x_forwarded_for:
        # The 'X-Forwarded-For' header can contain multiple IP addresses,
        # so we take the first one.
        client_ip = x_forwarded_for.split(",")[0]
    else:
        client_ip = request.client.host
    return {"client_ip": client_ip}

このコードでは、まずX-Forwarded-Forヘッダーをチェックします。このヘッダーが存在する場合、その最初のIPアドレス(クライアントのIPアドレス)を取得します。ヘッダーが存在しない場合、request.client.hostを使用してIPアドレスを取得します。

ただし、X-Forwarded-Forヘッダーは信頼できない可能性があります。なぜなら、このヘッダーはクライアントまたはプロキシによって設定され、偽造される可能性があるからです。したがって、この方法を使用する場合は注意が必要です。

次のセクションでは、FastAPIでのロギングの設定について説明します。お楽しみに!

FastAPIでのロギングの設定

FastAPIは、Pythonの標準的なloggingモジュールを使用してログを管理します。これにより、アプリケーションのログを柔軟にカスタマイズすることが可能です。

以下に、FastAPIでの基本的なロギングの設定方法を示します。

import logging
from fastapi import FastAPI

app = FastAPI()

# ロガーの設定
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
)

@app.get("/")
def read_root():
    logging.info("Root endpoint called")
    return {"Hello": "World"}

このコードでは、logging.basicConfig関数を使用してロギングの設定を行っています。levelパラメータは、ログに記録するメッセージの最低レベルを指定します。formatパラメータは、ログメッセージのフォーマットを指定します。

そして、エンドポイント内でlogging.info関数を使用して、情報レベルのログメッセージを記録しています。

次のセクションでは、実際のコード例とその説明について説明します。お楽しみに!

実際のコード例とその説明

以下に、FastAPIを使用してクライアントのIPアドレスをログに記録する完全なコード例を示します。

import logging
from fastapi import FastAPI, Request
from typing import Optional

app = FastAPI()

# ロガーの設定
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
)

@app.get("/get_my_ip")
async def get_my_ip(request: Request):
    x_forwarded_for: Optional[str] = request.headers.get("X-Forwarded-For")
    if x_forwarded_for:
        # The 'X-Forwarded-For' header can contain multiple IP addresses,
        # so we take the first one.
        client_ip = x_forwarded_for.split(",")[0]
    else:
        client_ip = request.client.host
    logging.info(f"Client IP: {client_ip}")
    return {"client_ip": client_ip}

このコードでは、まずロギングの設定を行っています。次に、/get_my_ipエンドポイントを定義しています。このエンドポイントでは、まずX-Forwarded-Forヘッダーをチェックします。このヘッダーが存在する場合、その最初のIPアドレス(クライアントのIPアドレス)を取得します。ヘッダーが存在しない場合、request.client.hostを使用してIPアドレスを取得します。最後に、取得したIPアドレスをログに記録します。

このコードを実行すると、クライアントが/get_my_ipエンドポイントにアクセスするたびに、そのIPアドレスがログに記録されます。

次のセクションでは、まとめと次のステップについて説明します。お楽しみに!

まとめと次のステップ

この記事では、FastAPIを使用してクライアントのIPアドレスをログに記録する方法について説明しました。まず、FastAPIとその主な特徴について説明しました。次に、クライアントのIPアドレスを取得する基本的な方法と、プロキシを介したリクエストの場合のIP取得方法について説明しました。その後、FastAPIでのロギングの設定方法と、クライアントのIPアドレスをログに記録する具体的なコード例について説明しました。

次のステップとしては、このコードを自分のFastAPIアプリケーションに組み込んでみることをお勧めします。また、X-Forwarded-Forヘッダーの信頼性についてさらに調査し、必要に応じてセキュリティ対策を強化することも重要です。

FastAPIはその高速性と柔軟性から多くの開発者に支持されています。この記事が、FastAPIを更に理解し、効果的に利用する一助となれば幸いです。Happy coding!

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です