Flask セッションのデコーディングとエンコーディングに基づく Starlette/FastAPI アプリケーション用のセッション ミドルウェア。
pip install starlette-flask
それで、何が問題なのでしょうか? Flask アプリケーションがあり、それが長期間稼働していたとしましょう。 FastAPI に移行したいが、ユーザーがセッション データを失うことは望ましくありません。正直に言うと、移行は簡単なプロセスではありません。ゆっくりと実行して、アプリケーションを別のアプリケーションにマウントするなどの FastAPI 機能のメリットを享受することをお勧めします。
Flask アプリケーションを FastAPI アプリケーションにマウントしてみましょう。
from fastapi import FastAPI , Request , Response
from flask import Flask , jsonify , session , request
from starlette . middleware . sessions import SessionMiddleware
from a2wsgi import WSGIMiddleware
secret_key = "super-secret"
flask_app = Flask ( __name__ )
flask_app . config [ "SECRET_KEY" ] = secret_key
@ flask_app . get ( "/" )
def flask_index ():
return jsonify ({ "message" : "Hello World from Flask Application" })
@ flask_app . get ( "/set-session" )
def flask_set_session ():
session [ "application" ] = "flask"
session . modified = True
return jsonify ({ "message" : "Session set" })
@ flask_app . get ( "/get-session" )
def flask_get_session ():
return jsonify ({ "message" : session . get ( "application" , None )})
@ flask_app . get ( "/delete-session" )
def flask_delete_session ():
session . pop ( "application" )
session . modified = True
return jsonify ({ "message" : "Session deleted" })
@ flask_app . before_request
def before_request ():
print ( session . items ())
@ flask_app . after_request
def after_request ( response ):
print ( session . items ())
return response
fastapi_application = FastAPI ()
fastapi_application . add_middleware (
SessionMiddleware ,
secret_key = secret_key ,
)
@ fastapi_application . middleware ( "http" )
async def starlette_add_process_time_header ( request : Request , call_next ):
response = await call_next ( request )
response . headers [ "X-Process-Time" ] = "100"
print ( response . headers )
return response
@ fastapi_application . get ( "/" )
async def starlette_index ( req : Request ):
return { "message" : "Hello World from FastAPI Application" }
@ fastapi_application . get ( "/set-session" )
async def starlette_set_session ( req : Request ):
req . session . update ({ "application" : "fastapi" })
return { "message" : "Session set" }
@ fastapi_application . get ( "/get-session" )
async def starlette_get_session ( req : Request ):
return { "message" : req . session . get ( "application" , None )}
@ fastapi_application . get ( "/delete-session" )
async def starlette_delete_session ( req : Request ):
req . session . pop ( "application" )
return { "message" : "Session deleted" }
app = FastAPI ()
app . mount ( "/flask-application" , WSGIMiddleware ( flask_app ))
app . mount ( "/fastapi-application" , fastapi_application )
ここでの問題は次のとおりです。Flask アプリケーションでセッションを設定すると、FastAPI アプリケーションからセッションを取得できず、その逆も同様です。同時に、これら 2 つのアプリケーションは、セッション データにアクセスするだけでなく、互いのセッション データを上書きします。これは、セッション データに署名するために異なる方法を使用しているためです。
これらは異なる方法を使用してセッション データに署名するため、互いのセッション データをデコードすることはできません。何ができるでしょうか?この問題を解決するには、 starlette-flask
使用できます。
必要なのはこれだけです:
- from starlette.middleware.sessions import SessionMiddleware
+ from starlette_flask.middleware.sessions import SessionMiddleware
Flask から FastAPI に移行していたところ、既存の Flask アプリケーションを FastAPI (a2wsgi のおかげ) アプリケーションで使用できることがわかりました。
これは言わなければなりません: 私の Flask アプリケーションの多くは、Flask Admin、Flask Login、Flask-JWT-Extended などのサードパーティの Flask 拡張機能に依存しています。
そこで、Flask と FastAPI を結合する方法を探したところ、方法を見つけました。しかし問題がありました...Flask と FastAPI アプリケーション間のセッション データにアクセスできませんでした。つまり、Flask 側と FastAPI 側でセッション データを CRUD することはできましたが、Flask によって CRUD された FastAPI 内のセッション データを CRUD することができなかったので、この議論を FastAPI リポジトリで開始しました。当時はこれを解決できなかったので、Flask Login と Flask Admin はもう使わないことにしました...
しかし、3月から9月までの議論では何の答えも得られなかったことがわかります。面倒だったので自分で解決することにしました。 FlaskとStarlette(FastAPIのバックエンドコア)のソースコードを見てみました。彼らはセッション データに署名するために異なる方法を使用していることがわかり、Starlette はセッション データが作成、更新、削除、さらには読み取られていない場合でも、セッション データに再署名し続けました。それが問題でした。カスタムのSessionMiddleware
が必要でした。 Flask と同じメソッドを使用してセッション データに署名し、それを実装しました。
関連するディスカッション/問題/プル リクエストは次のとおりです。
allow_path_regex
SessionMiddleware
に追加しました · プル リクエスト #2316 · encode/starlette別の関連プロジェクトは次のとおりです: volfpeter/fastapi-flask-auth: アクセス制御に Flask セッション Cookie を使用する軽量の FastAPI 依存関係と認証システム。実際、このプロジェクトは私にstarlette-flask
の構築のインスピレーションを与えました。
Starlette のミドルウェアの詳細については、「ミドルウェア - Starlette」ページをご覧ください。
私はセキュリティの専門家ではありません。この問題に対する私の解決策を共有したかっただけです。ご提案がある場合は、問題またはプルリクエストを開いてください。
Starlette に付属するデフォルトの
SessionMiddleware
に関する問題や議論もいくつかあります。私の実装は完璧ではなく、Starlette に付属するデフォルトのSessionMiddleware
のどちらかだと思います。
starlette-flask
MIT ライセンスの条件に基づいて配布されます。