FastAPI/Starlette 的 SessionMiddleware 为每个请求创建新会话

28 *_*cky 4 python session session-cookies starlette fastapi

我需要在session_set端点中创建一个用于身份验证的会话。但是,由于某种原因,会话仍在端点中创建session_info。如何使会话仅在中创建session_set?否则,我会在每个请求的响应中都有一个新会话。

这是我的代码:

import uvicorn
from fastapi import FastAPI, Request
from starlette.middleware.sessions import SessionMiddleware

app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="some-random-string", max_age=None)


@app.get("/a")
async def session_set(request: Request):
    request.session["my_var"] = "1234"
    return 'ok'


@app.get("/b")
async def session_info(request: Request):
    my_var = request.session.get("my_var", None)
    return my_var


if __name__ == '__main__':
    uvicorn.run('http-session:app', port=5000, reload=True)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在此输入图像描述

Chr*_*ris 5

每次新请求到达时,您可以使用中间件来覆盖cookiesession中的值(也请查看Starlette 中的文档);因此,Responsesession保持不变。

注意:请记住添加到SessionMiddleware实例后声明您的自定义中间件app,因为应用程序中定义端点/子应用程序的顺序很重要,如本答案中所述(请参阅相关的FastAPI 文档中所述(另

工作示例:

from fastapi import FastAPI, Request
from starlette.middleware.sessions import SessionMiddleware

app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="some-random-string")

@app.middleware("http")
async def some_middleware(request: Request, call_next):
    response = await call_next(request)
    session = request.cookies.get('session')
    if session:
        response.set_cookie(key='session', value=request.cookies.get('session'), httponly=True)
    return response
 
@app.get("/a")
def func_a(request: Request):
    request.session["my_var"] = "1234"
    print(request.cookies.get('session'))
    return 'OK'

@app.get("/b")
def func_b(request: Request):
    my_var = request.session.get("my_var", None)
    print(request.cookies.get('session'))
    return my_var
Run Code Online (Sandbox Code Playgroud)