このコンテンツではFastAPIでWebアプリケーションによく使われるJWT認証を実装する方法を紹介します。
前提として、PythonやFastAPIにある程度慣れ親しんでいるエンジニアが対象です。
FastAPIの細かな仕様については触れません。
まずは、必要なライブラリをインストールしましょう。
通常のFastAPIアプリケーションへ必要なライブラリ以外にpython-multipart
とpython-jose
のインストールが必要です。
まずは簡単なFastAPIアプリケーションを作成しましょう。
今回はapp.py
を作っていきます。
この状態で以下のコマンドを実行することで、ブラウザでhttp://localhost:8000
を開くとアプリケーションの立ち上がりが確認できます。
ベースとなるアプリケーションができたところで、JWTに必要なファイル群とディレクトリ構成を説明します。
頑張れば1つのファイルにまとめられますが、実際にプロジェクトを開始した場合、こういった形でいくつかのファイルに分けておくと使い勝手が良いです。
慣れていないとJWT認証は何をどう実装すればいいかわかりづらいため、実装の流れを列挙します。
これで最低限の機能が実装できます。
それではルーティングを実装していきましょう。まずは、routes/auth.py
を作成します。
次に、このルーターを最初に作成したapp.py
で読み込みます。
こうすることで、http://localhost:8000/auth
をプレフィックスとしたURLルーティングが作成できます。
次に、utils/jwt.py
を作成しましょう。このjwt.py
でJWTのクレームセットと呼ばれるJSONのデータセットを出力させます。
ここでJWTのエンコーダーとデコーダーも実装しておきます。
token_type
を引数としている理由は、このコンテンツでは紹介しませんが、リフレッシュトークンという期限切れを解消するタイプのトークンを発行するときのためです。
この認証情報ロジックをルーティングで呼び出します。
ここまで実装できると、このhttp://localhost:8000/auth/token
ルーティングが確認できます。以下はPostmanでAPIを確認した例です。(認証は含まれていないのでusername
、password
はなんでもOK)
アクセストークン取得例
そしてここからミドルウェアの実装です。このあたりは若干複雑となっているので逐一説明していきます。
まずは、utils/auth.py
に認証ユーザーと未認証ユーザーの定義をしましょう。FastAPIと共にインストールされるstarlette
にベースがあるので使いましょう。
そして、この定義を使ってミドルウェアを作っていきます。
ここで何をしているか下記に列挙します。
Authorization
を取得し、データ化Bearer
が含まれていない、期限切れ、JWTとして不適切、その他エラーの場合は認証不可以上となります。
そして、このミドルウェアをapp.py
で呼び出しましょう。事前準備として、middlewares/__init__.py
を作成してインポートできるようにします。
次にapp.py
の編集です。
ミドルウェアとしての機能は備わったものの、これだけではリクエストに対して認証は機能しません。
最後に、ルーティングに対して依存関係を実装しましょう。この依存関係をルーティングごとに設定できることで、ログインAPIなどの「認証していないユーザーがリクエストしたいルーティング」が有効となります。
まずは作成したutils/auth.py
にFastAPIのリクエストを利用したアクセストークンを返すクラスを実装しましょう。
次に依存注入ロジックを実装します。utils/dependency.py
を作成しましょう。
この依存ロジックをルーティングに設定することで、トークンを持ったリクエストでなければ受け付けないようになります。
app.py
に設定してみましょう。
ここで実際に動作確認してみます。ブラウザでhttp://localhost:8000/
にアクセスすると、以下のように表示されます。
次に、成功した場合として先ほど動作確認したhttp://localhost:8000/auth/token
で取得したアクセストークンをヘッダーに含めてPOSTリクエストしてみます。以下のように、ヘッダーにAuthorization
とアクセストークンを含めてリクエストしてみます。
認証付きリクエスト
正しくレスポンスが得られたので成功です。
ここまで、FastAPI + JWTの実装を見てきました。
JWT認証はWebアプリケーション開発系のバックエンドエンジニアは実装する機会が多いため身につけておきたいスキルです。より深くJWTの構造理解をしたい場合は、以下のJWT仕様について書かれた以下のページを参考にすると良いでしょう。
理解を深めればセキュリティへの意識も高まるので、積極的に手を動かしながら学んでいきたいところです。