البرامج الوسيطة للجلسة لتطبيقات Starlette/FastAPI المستندة إلى فك تشفير جلسة Flask وترميزها.
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، والعكس صحيح. وفي الوقت نفسه، بالإضافة إلى الوصول إلى بيانات الجلسة، يقوم هذان التطبيقان بالكتابة فوق بيانات جلسة بعضهما البعض. وذلك لأنهم يستخدمون طرقًا مختلفة للتوقيع على بيانات الجلسة.
ونظرًا لأنهم يستخدمون طرقًا مختلفة لتوقيع بيانات الجلسة، فلا يمكنهم فك تشفير بيانات جلسة بعضهم البعض. ماذا يمكننا أن نفعل؟ يمكننا استخدام starlette-flask
لحل هذه المشكلة.
كل ما عليك فعله هو هذا:
- from starlette.middleware.sessions import SessionMiddleware
+ from starlette_flask.middleware.sessions import SessionMiddleware
كنت أقوم بالترحيل من Flask إلى FastAPI واكتشفت أنه يمكنني استخدام تطبيقات Flask الحالية مع تطبيق FastAPI (بفضل a2wsgi).
يجب أن أخبرك بهذا: تعتمد العديد من تطبيقات Flask الخاصة بي على ملحقات Flask التابعة لجهات خارجية مثل Flask Admin وFlask Login وFlask-JWT-Extending.
لذلك بحثت عن كيفية ربط Flask وFastAPI ووجدت طريقة. ولكن حدثت مشكلة... لم أتمكن من الوصول إلى بيانات الجلسة بين تطبيقات Flask وFastAPI. أعني أنني تمكنت من CRUD بيانات الجلسة على جانب Flask وجانب FastAPI ولكن لم أتمكن من CRUD بيانات الجلسة داخل FastAPI التي تم CRUDed بواسطة Flask، لذلك بدأت هذه المناقشة في مستودع FastAPI. في ذلك الوقت لم أتمكن من حل هذه المشكلة، لذلك قررت عدم استخدام Flask Login وFlask Admin بعد الآن...
ولكن يمكنك أن ترى أن المناقشة لم تحصل على أي إجابات في الفترة من مارس إلى سبتمبر. كان الأمر يزعجني، لذلك قررت حل المشكلة بنفسي. لقد ألقيت نظرة على الكود المصدري لـ Flask وStarlette (الواجهة الخلفية لـ FastAPI). لقد وجدت أنهم استخدموا طرقًا مختلفة للتوقيع على بيانات الجلسة وواصلت Starlette إعادة توقيع بيانات الجلسة حتى لو لم يتم إنشاؤها أو تحديثها أو حذفها أو حتى قراءتها، كانت هذه هي المشكلة... كنت بحاجة إلى برنامج SessionMiddleware
مخصص يستخدم نفس طريقة Flask للتوقيع على بيانات الجلسة وقد قمت بتنفيذها.
فيما يلي بعض المناقشات/القضايا/طلبات السحب ذات الصلة:
allow_path_regex
إلى SessionMiddleware
بواسطة hasansezertasan · سحب الطلب رقم 2316 · ترميز/starlette إليك مشروع آخر ذي صلة: volfpeter/fastapi-flask-auth: تبعيات FastAPI خفيفة الوزن ومُصادق يستخدم ملفات تعريف الارتباط لجلسة Flask للتحكم في الوصول. لقد ألهمني هذا المشروع في الواقع لبناء starlette-flask
.
راجع صفحة البرامج الوسيطة - Starlette لمعرفة المزيد حول البرامج الوسيطة في Starlette.
أنا لست خبيرا أمنيا. أردت فقط أن أشارك الحل الخاص بي لهذه المشكلة. إذا كان لديك أي اقتراحات، يرجى فتح قضية أو طلب سحب.
هناك أيضًا بعض المشكلات والمناقشات حول مشكلات برنامج
SessionMiddleware
الافتراضي الذي يأتي مع Starlette. أعتقد أن تطبيقي ليس مثاليًا، بل هو برنامجSessionMiddleware
الافتراضي الذي يأتي مع Starlette.
يتم توزيع starlette-flask
بموجب شروط ترخيص معهد ماساتشوستس للتكنولوجيا.