You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

aiohttp路由间共享用户数据问题:session在GET/POST间无法互通

解决aiohttp_session跨GET/POST请求session不共享的问题

核心问题分析

你遇到的session不共享问题,主要有两个关键原因:

  1. 每次服务器重启生成新的加密密钥:代码中每次启动creat_server都会调用fernet.Fernet.generate_key()生成新密钥,导致之前设置的session cookie无法被新密钥解密,服务器会自动创建新的session。
  2. (可能的次要原因)session未被正确关联到响应:虽然aiohttp_session中间件会自动处理session保存,但部分响应类型(如FileResponse)可能需要确保cookie被正确附加。

具体修复步骤

1. 固定加密密钥

不要每次启动服务器生成新密钥,生成一次后固定下来:

# __init__.py
async def creat_server():
    app = Application()

    app["db"] = await connect_to_mongodb()

    app.middlewares.append(db_middleware)

    # 生成一次密钥后固定(示例密钥,实际请自己生成并替换)
    # 生成密钥的方法:单独运行一次print(fernet.Fernet.generate_key())并复制结果
    fernet_key = b'your-generated-fernet-key-here'
    secret_key = base64.urlsafe_b64decode(fernet_key)

    app.router.add_static("/static", os.path.join(os.path.dirname(__file__), "static"))
    aiohttp_jinja2.setup(
        app,
        loader=jinja2.FileSystemLoader(
            os.path.join(os.path.dirname(__file__), "templates")
        ),
    )
    setup_routes(app)
    setup(app, EncryptedCookieStorage(secret_key))

    return app

2. 确保session在GET请求中正确保存(可选验证)

在Login视图的GET方法中,显式调用session.save()确保session被写入响应cookie:

# views.py
async def get(self):
    object_id = await init_user(self.request.app["db"])
    session = await get_session(self.request)
    session["object_id"] = object_id
    await session.save()  # 显式保存session
    print("\n\nhere0", session["object_id"], "\n\n")
    return FileResponse(os.path.join(BASE_DIR, "login.html"))

3. 验证请求的session一致性

在GET和POST方法中打印session的唯一标识,确认是否为同一个session:

# views.py
async def get(self):
    object_id = await init_user(self.request.app["db"])
    session = await get_session(self.request)
    session["object_id"] = object_id
    await session.save()
    print("\n\nhere0 session id:", session.identity, "object_id:", session["object_id"], "\n\n")
    return FileResponse(os.path.join(BASE_DIR, "login.html"))

async def post(self):
    data = await self.request.post()
    phone_number = data.get("phone", "")
    session = await get_session(self.request)
    print("\n\nhere1 session id:", session.identity, "object_id:", session.get("object_id"), "\n\n")
    print("Phone number submitted:", phone_number)
    # add_phone(self.request.app['db'], self.object_id, self.request.form["phone"])
    return web.HTTPFound("/welcome-policy")

额外检查项

  • 确认浏览器未禁用cookie,POST请求是否携带了GET请求设置的AIOHTTP_SESSION cookie。
  • 检查db_middleware是否修改了request或响应对象,导致session cookie被意外移除。

内容的提问来源于stack exchange,提问作者Sina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:55:23