FastAPIは高性能なPythonのWeb APIフレームワークですが、セッション管理機能は標準では提供されていません。Flaskのようなシンプルなセッション管理を実現するためには、StarletteのSessionMiddlewareを活用します。
この記事では、FastAPIでSessionMiddlewareを使ってHTTPセッションを管理する方法と、具体的な応用例としてGoogle OAuth 2.0を用いたWebサーバーアプリケーションでの認証フローにおけるセッション管理の実装を紹介します。
FastAPIでのセッション管理
まず、SessionMiddlewareをFastAPIアプリケーションに追加します。
from fastapi import FastAPI
from starlette.middleware.sessions import SessionMiddleware
app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="your_secret_key")SessionMiddlewareは署名付きクッキーを使ってHTTPセッションを実現します。
secret_keyは署名用の秘密鍵で、ランダムな文字列を設定する必要があります。
os.urandom(24).hex()などで生成した値を環境変数経由で読み込むのが一般的です。
セッション変数の設定、取得は以下のように行います。
from fastapi import FastAPI
from starlette.middleware.sessions import SessionMiddleware
app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="your_secret_key")
@app.get("/set_session")
async def set_session(request: Request):
#セッション変数の設定
request.session["state"] = "test"
return 'session data set'
@app.get("/get_session")
async def get_session(request: Request):
#セッション変数の取得
var = request.session.get("state")
return varGoogle OAuth 2.0 での活用例
WebアプリケーションでGoogle OAuth 2.0を実装する場合、セッション管理を実装する必要があります。
公式サイトではFlaskでの実装例が載っていますが、ここではGoogleの認証サーバーを利用したログイン機能をFastAPIで実装してみます。
import os
from dotenv import load_dotenv
from fastapi import Request, FastAPI
from fastapi.responses import RedirectResponse
from starlette.middleware.sessions import SessionMiddleware
from google_auth_oauthlib.flow import Flow
load_dotenv()
#クライアントシークレットのパスを環境変数から取得
client_secret = os.getenv('CLIENT_SECRET_PATH')
#セッションの秘密鍵
session_secret_key = os.getenv('SESSION_SECRET_KEY')
# OAuth 2.0 のスコープ (アプリケーションがアクセスを要求するGoogle APIの範囲)
# 今回はGoogle Drive APIへの基本的なアクセス権限をリクエスト
SCOPES = ["https://www.googleapis.com/auth/drive"]
app = FastAPI()
#SessionMiddlewareの定義
app.add_middleware(SessionMiddleware, secret_key= session_secret_key)
@app.get("/login")
async def login(request: Request):
#OAuth 2.0 flowオブジェクトを作成
flow = Flow.from_client_secrets_file(
client_secret, SCOPES
)
#認証後のリダイレクトURIを指定
flow.redirect_uri = request.url_for('oauth2callback')
"""
認証ページのURLとstateを生成
stateはCSRF(Cross-Site Request Forgery) 攻撃を防ぐために重要
"""
authorization_url, state = flow.authorization_url(
access_type= 'offline',
include_granted_scopes= 'true'
)
"""
生成されたstateをセッションに保存
コールバック時にこのstateを検証する
"""
request.session['state'] = state
#ユーザをGoogleの認証ページにリダイレクト
return RedirectResponse(authorization_url)
@app.get("/oauth2callback")
async def oauth2callback(request: Request):
"""
認証サーバーからのレスポンスからstateを取得し、事前に生成したstateと比較検証する
これにより、認証フローが正当なものであることを確認
"""
state = request.session.get('state')
flow = Flow.from_client_secrets_file(
client_secret, scopes=SCOPES, state=state)
flow.redirect_uri = request.url_for('oauth2callback')
#認証サーバーからのレスポンスからアクセストークンを取得する
authorization_response = str(request.url)
flow.fetch_token(authorization_response=authorization_response)
creds = flow.credentials
#認証情報をJSON形式でセッションに保存
request.session["credentials"] = creds.to_json()
#ログイン成功後、トップページなどにリダイレクト
return RedirectResponse("/")
@app.get("/")
async def root():
return {"message": "ログインに成功しました"}
まとめ
FastAPIでのセッション管理は、StarletteのSessionMiddlewareを活用することで実現できます。request.sessionを通じて、ログイン状態や一時的な認証情報などの状態を簡単に保持・参照できます。本記事で紹介したGoogle OAuth 2.0との組み合わせにより、実用的なログイン機能を構築することが可能です。
上記の方法も活用した、自動名刺読み取りアプリも作成していますので、もしよければご覧ください。

参考資料


コメント