FastAPIでAPIサーバーを構築しているものの、認証機能の実装で悩んでいませんか。セキュリティを考慮した認証機能がなければ、せっかく構築したAPIも無防備な状態になってしまいます。特にJWT(JSON Web Token)の実装は、トークンの生成、検証、有効期限管理など複数の要素が絡み合い、初心者にとっては難しく感じられるでしょう。
本記事では、FastAPIを使ったJWT認証の実装方法を、初心者からベテランエンジニアまで実務で使える形でステップバイステップで解説します。セキュリティベストプラクティスに則った実装コードも用意しているため、すぐに本番環境で活用できる内容になっています。
FastAPI認証実装の前に知るべき基礎知識
JWT認証を理解する前に、なぜFastAPIでJWT認証が選ばれるのかを知ることが重要です。従来のセッションベース認証と異なり、JWTはステートレスな設計が特徴です。
つまり、サーバー側でセッション情報を保持する必要がなく、スケーラビリティに優れています。マイクロサービスアーキテクチャや複数のサーバーインスタンスを運用する場合、JWTは特に有効です。
JWT認証の流れは以下の通りです。
- ユーザーがログイン情報(ユーザー名とパスワード)を送信する
- サーバーが認証情報を検証し、JWTトークンを生成して返す
- クライアントがそのトークンをリクエストヘッダーに含めて送信する
- サーバーがトークンの署名を検証し、有効期限をチェックする
- 検証が成功すれば、リソースへのアクセスを許可する
FastAPI環境のセットアップと必要なライブラリ
FastAPIでJWT認証を実装するには、複数のライブラリが必要になります。まず必要なパッケージをインストールしましょう。
pip install fastapi uvicorn python-jose python-multipart passlib[bcrypt] pydantic pydantic-settings
各ライブラリの役割は以下の通りです。
- fastapi:Webフレームワーク本体
- uvicorn:ASGIサーバー
- python-jose:JWTトークンの生成・検証
- passlib:パスワードのハッシュ化
- pydantic:データバリデーション。最新版ではPydantic v2への移行により仕様が変わっているため、Pydantic v2への移行で破壊的変更に対応する実例ガイドを参考に対応することをお勧めします。
環境構築が完了したら、次はセキュリティ設定の実装に進みます。
セキュアなパスワード管理の実装
ユーザーのパスワードをデータベースに平文で保存してはいけません。必ずハッシュ化して保存する必要があります。FastAPIではpasslibライブラリを使用してこを実現します。
from passlib.context import CryptContext
# bcryptアルゴリズムを使用してパスワードをハッシュ化
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def hash_password(password: str) -> str:
"""パスワードをハッシュ化する関数"""
return pwd_context.hash(password)
def verify_password(plain_password: str, hashed_password: str) -> bool:
"""入力されたパスワードとハッシュ化されたパスワードを検証する関数"""
return pwd_context.verify(plain_password, hashed_password)
この実装により、ユーザー登録時にはパスワードを自動的にハッシュ化し、ログイン時には入力されたパスワードとデータベースに保存されたハッシュ値を比較検証します。データベースとの連携については、SQLAlchemy 2.0の非同期セッション管理を完全解説で詳しく解説していますので、併せてご参照ください。