Sitzungs-Middleware für Starlette/FastAPI-Anwendungen basierend auf Flask Session Decoding und Encoding.
pip install starlette-flask
Was ist also das Problem? Nehmen wir an, Sie haben eine Flask-Anwendung und diese war lange Zeit live. Sie möchten zu FastAPI migrieren, möchten aber nicht, dass Ihre Benutzer ihre Sitzungsdaten verlieren. Und um ehrlich zu sein: Migration ist kein einfacher Prozess. Vielleicht möchten Sie es langsam angehen lassen und die Vorteile von FastAPI-Funktionen nutzen, z. B. das Mounten einer Anwendung in eine andere Anwendung.
Versuchen wir, eine Flask-Anwendung in eine FastAPI-Anwendung einzubinden.
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 )
Das Problem hier ist folgendes: Wenn Sie eine Sitzung in der Flask-Anwendung einrichten, können Sie sie nicht von der FastAPI-Anwendung abrufen und umgekehrt. Gleichzeitig überschreiben diese beiden Anwendungen über den Zugriff auf die Sitzungsdaten hinaus auch die Sitzungsdaten der jeweils anderen. Das liegt daran, dass sie unterschiedliche Methoden zum Signieren der Sitzungsdaten verwenden.
Da sie unterschiedliche Methoden zum Signieren der Sitzungsdaten verwenden, können sie die Sitzungsdaten der anderen nicht entschlüsseln. Was können wir tun? Wir können starlette-flask
verwenden, um dieses Problem zu lösen.
Alles, was Sie tun müssen, ist Folgendes:
- from starlette.middleware.sessions import SessionMiddleware
+ from starlette_flask.middleware.sessions import SessionMiddleware
Ich bin von Flask zu FastAPI migriert und habe herausgefunden, dass ich meine vorhandenen Flask-Anwendungen mit der FastAPI-Anwendung (dank a2wsgi) verwenden kann.
Ich muss Ihnen Folgendes sagen: Viele meiner Flask-Anwendungen hängen von Flask-Erweiterungen von Drittanbietern wie Flask Admin, Flask Login und Flask-JWT-Extended ab
Also habe ich nach Möglichkeiten gesucht, Flask und FastAPI zu koppeln, und einen Weg gefunden. Es gab jedoch ein Problem: Ich konnte nicht auf die Sitzungsdaten zwischen Flask- und FastAPI-Anwendungen zugreifen. Ich meine, ich konnte Sitzungsdaten auf der Flask-Seite und auf der FastAPI-Seite CRUDen, aber ich konnte die Sitzungsdaten innerhalb von FastAPI, die von Flask CRUDiert wurden, nicht CRUDEN, also habe ich diese Diskussion im FastAPI-Repository begonnen. Damals konnte ich das Problem nicht lösen, also habe ich beschlossen, Flask Login und Flask Admin nicht mehr zu verwenden ...
Man sieht aber, dass die Diskussion von März bis September keine Antworten erhielt. Es störte mich, also beschloss ich, es selbst zu lösen. Ich habe mir den Quellcode von Flask und Starlette (Backend-Kern von FastAPI) angesehen. Ich stellte fest, dass sie unterschiedliche Methoden zum Signieren der Sitzungsdaten verwendeten und Starlette die Sitzungsdaten immer wieder neu signierte, auch wenn sie nicht erstellt, aktualisiert, gelöscht oder gar gelesen wurden, das war das Problem ... Dafür brauchte ich eine benutzerdefinierte SessionMiddleware
verwendet die gleiche Methode wie Flask, um die Sitzungsdaten zu signieren, und ich habe sie implementiert.
Hier sind einige verwandte Diskussionen/Probleme/Pull-Requests:
allow_path_regex
zur SessionMiddleware
hinzugefügt von hasansezertasan · Pull Request #2316 · encode/starlette Hier ist ein weiteres verwandtes Projekt: volfpeter/fastapi-flask-auth: Leichte FastAPI-Abhängigkeiten und Authentifikator, der Flask-Sitzungscookies zur Zugriffskontrolle verwendet. Dieses Projekt hat mich tatsächlich dazu inspiriert, starlette-flask
zu bauen.
Schauen Sie sich die Seite „Middleware – Starlette“ an, um mehr über Middlewares in Starlette zu erfahren.
Ich bin kein Sicherheitsexperte. Ich wollte nur meine Lösung für dieses Problem mitteilen. Wenn Sie Vorschläge haben, öffnen Sie bitte ein Problem oder eine Pull-Anfrage.
Es gibt auch einige Probleme und Diskussionen über Probleme mit der Standard
SessionMiddleware
, die mit Starlette geliefert wird. Ich glaube, meine Implementierung ist nicht perfekt, aber entweder die StandardSessionMiddleware
, die mit Starlette geliefert wird.
starlette-flask
wird unter den Bedingungen der MIT-Lizenz vertrieben.