Да, компоненты промежуточного программного обеспечения, добавленные в приложение в правильном порядке , могут обращаться к хранилищу сеансов, установленному промежуточным программным обеспечением сеанса.
Документация aiohttp
охватывает порядок приоритетов для компонентов промежуточного программного обеспечения в их Промежуточном программном обеспечении раздел :
Внутренне, один обработчик запросов создается путем применения цепочки промежуточного программного обеспечения к исходному обработчику в обратном порядке и вызывается RequestHandler
как обычный обработчик .
Далее они используют пример, чтобы продемонстрировать, что это значит. Таким образом, они используют два компонента промежуточного программного обеспечения, которые сообщают о своем входе и выходе и добавляют их в список app.middlewares
в следующем порядке:
... middlewares=[middleware1, middleware2]
Этот порядок дает следующий результат:
Middleware 1 called
Middleware 2 called
Handler function called
Middleware 2 finished
Middleware 1 finished
Таким образом, входящий запрос передается по другому промежуточному программному обеспечению в том же порядке, в котором они добавляются в список app.middlewares
.
Далее, aiohttp_session
также документирует, как они добавляют свое промежуточное программное обеспечение сеанса, в записи API для aiohttp_session.setup()
:
Функция ярлыка для:
app.middlewares.append(session_middleware(storage))
Таким образом, их компонент промежуточного программного обеспечения добавляется в конец списка. В соответствии с вышесказанным это означает, что все, что требует доступа к сеансу, должно идти после этого компонента промежуточного программного обеспечения.
Все, что делает промежуточное программное обеспечение сеанса, это добавляет хранилище к запросу под ключом aiohttp_session.STORAGE_KEY
; это делает сеансы доступными для любых последующих компонентов промежуточного программного обеспечения, которые следуют за ним. Компонентам промежуточного программного обеспечения не нужно делать ничего особенного, кроме добавления после промежуточного программного обеспечения сеанса, и оставить объект хранилища добавленным к запросу на месте. Объект запроса предназначен для совместного использования данных между компонентами .
Ваш код помещает все компоненты промежуточного программного обеспечения перед компонентом промежуточного программного обеспечения сеанса:
middleware.setup(app)
# ...
aiohttp_session.setup(app, EncryptedCookieStorage(session_key))
Это дает вам заказ [..., refresh_token_middleware, ..., session_middleware]
, и ваше промежуточное ПО не может получить доступ к любой информации о сеансе.
Так что вы должны поменять местами заказ; сначала вызовите aiohttp_session.setup()
, а затем добавьте свои собственные компоненты:
aiohttp_session.setup(app, EncryptedCookieStorage(session_key))
middleware.setup(app)
Если у вас все еще есть проблемы с доступом к хранилищу сеансов, это означает, что один из промежуточных компонентов промежуточного программного обеспечения снова удаляет информацию о хранилище сеансов .
Вы можете использовать следующую фабрику промежуточного программного обеспечения в разных местах, чтобы сообщить о наличии хранилища сеансов, чтобы помочь вам отладить это:
from aiohttp import web
from aiohttp_session import STORAGE_KEY
COUNTER_KEY = "__debug_session_storage_counter__"
_label = {
False: "\x1b[31;1mMISSING\x1b[0m",
True: "\x1b[32;1mPRESENT\x1b[0m",
}
def debug_session_storage(app):
pre = nxt = ""
if app.middlewares:
previous = app.middlewares[-1]
name = getattr(previous, "__qualname__", repr(previous))
pre = f" {name} ->"
nxt = f" {name} <-"
@web.middleware
async def middleware(request, handler):
counter = request.get(COUNTER_KEY, -1) + 1
request[COUNTER_KEY] = counter
found = STORAGE_KEY in request
indent = " " * counter
print(f"{indent}-{pre} probe#{counter} - storage: {_label[found]}")
try:
return await handler(request)
finally:
print(f"{indent}-{nxt} probe#{counter} - done")
app.middlewares.append(middleware)
Если вы вставите это между каждым элементом промежуточного программного обеспечения, которое вы добавите, вы сможете выяснить, если и где хранилище сеанса теряется:
def setup(app):
# start with a probe
debug_session_storage(app)
for filename in listdir('middleware'):
if filename[-2:] == 'py' and filename[:2] != '__':
module = __import__('rpdashboard.middleware.' + filename[:-3], fromlist=['middleware'])
app.middlewares.append(module.middleware)
# Add debug probe after every component
debug_session_storage(app)
Это должно сказать вам
- какой компонент промежуточного программного обеспечения предшествовал каждому исследованию
- если имеется хранилище сеанса, с использованием зеленого и красного цветов ANSI, чтобы его было легко обнаружить
- если есть, полностью сбросили запрос; если отсчет проб начинается снова с 0, тогда что-то очищает не только сеансовый ключ, но и счётчик проб!