Session Middleware untuk Aplikasi Starlette/FastAPI berdasarkan Decoding dan Encoding Sesi Flask.
pip install starlette-flask
Jadi apa masalahnya? Katakanlah Anda memiliki aplikasi Flask dan sudah aktif untuk waktu yang lama. Anda ingin bermigrasi ke FastAPI tetapi tidak ingin pengguna kehilangan data sesinya. Dan sejujurnya, migrasi bukanlah proses yang mudah. Anda mungkin ingin melakukannya secara perlahan dan memanfaatkan fitur FastAPI seperti memasang aplikasi ke aplikasi lain.
Mari kita coba mount aplikasi Flask ke aplikasi 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 )
Masalahnya disini: Jika Anda menyetel sesi di aplikasi Flask, Anda tidak bisa mendapatkannya dari aplikasi FastAPI, dan sebaliknya. Pada saat yang sama, selain mengakses data sesi, kedua aplikasi ini saling menimpa data sesi lainnya. Itu karena mereka menggunakan metode berbeda untuk menandatangani data sesi.
Karena mereka menggunakan metode berbeda untuk menandatangani data sesi, mereka tidak dapat memecahkan kode data sesi satu sama lain. Apa yang bisa kita lakukan? Kita bisa menggunakan starlette-flask
untuk mengatasi masalah ini.
Yang perlu Anda lakukan hanyalah ini:
- from starlette.middleware.sessions import SessionMiddleware
+ from starlette_flask.middleware.sessions import SessionMiddleware
Saya bermigrasi dari Flask ke FastAPI dan ternyata saya dapat menggunakan aplikasi Flask yang ada dengan aplikasi FastAPI (berkat a2wsgi).
Saya harus memberi tahu Anda ini: Banyak aplikasi Flask saya bergantung pada ekstensi Flask pihak ketiga seperti Flask Admin, Flask Login, dan Flask-JWT-Exended
Jadi saya mencari cara memasangkan Flask dan FastAPI dan menemukan caranya. Tapi ada masalah... Saya tidak bisa mengakses data sesi antara aplikasi Flask dan FastAPI. Maksud saya, saya dapat melakukan CRUD data sesi di sisi Flask dan FastAPI tetapi saya tidak dapat melakukan CRUD data sesi di dalam FastAPI yang di-CRUD oleh Flask, jadi saya memulai diskusi ini di repositori FastAPI. Dulu saya tidak bisa menyelesaikannya, jadi saya putuskan untuk tidak menggunakan Flask Login dan Flask Admin lagi...
Namun Anda dapat melihat bahwa diskusi tersebut tidak mendapatkan jawaban apa pun pada bulan Maret hingga September. Itu mengganggu saya, jadi saya memutuskan untuk menyelesaikannya sendiri. Saya melihat kode sumber Flask dan Starlette (inti backend FastAPI). Saya menemukan bahwa mereka menggunakan metode berbeda untuk menandatangani data sesi dan Starlette terus menandatangani ulang data sesi meskipun tidak dibuat, diperbarui, dihapus, atau bahkan dibaca, itulah masalahnya... Saya memerlukan SessionMiddleware
khusus yang menggunakan metode yang sama seperti Flask untuk menandatangani data sesi dan saya menerapkannya.
Berikut adalah beberapa diskusi/masalah/permintaan tarik terkait:
allow_path_regex
ke SessionMiddleware
oleh hasansezertasan · Permintaan Tarik #2316 · encode/starlette Berikut proyek terkait lainnya: volfpeter/fastapi-flask-auth: Dependensi FastAPI ringan dan autentikator yang menggunakan cookie sesi Flask untuk kontrol akses. Proyek ini sebenarnya menginspirasi saya untuk membuat starlette-flask
.
Lihat Middleware - halaman Starlette untuk mempelajari lebih lanjut tentang middleware di Starlette.
Saya bukan ahli keamanan. Saya hanya ingin berbagi solusi saya untuk masalah ini. Jika Anda memiliki saran, silakan buka masalah atau permintaan tarik.
Ada juga beberapa masalah dan diskusi tentang masalah dengan
SessionMiddleware
default yang disertakan dengan Starlette. Saya yakin implementasi saya tidak sempurna tetapiSessionMiddleware
default yang disertakan dengan Starlette.
starlette-flask
didistribusikan berdasarkan ketentuan lisensi MIT.