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

FastAPI+Starlette中间件会话问题:重定向后无法访问会话数据

FastAPI + Azure B2C 会话用户数据丢失问题排查与解决

核心排查方向

  • 中间件冲突干扰会话处理
  • SessionMiddleware 配置错误
  • MSAL 缓存读写逻辑异常
  • Cookie 跨域/属性设置问题
  • 重定向时会话未正确提交

具体解决方案

1. 移除自定义会话中间件,避免与Starlette默认中间件冲突

你的代码中同时使用了Starlette的SessionMiddleware和自定义的session_middleware,后者会覆盖默认的会话cookie处理逻辑,导致会话数据无法正确持久化。直接删除自定义中间件:

# 删掉这段冗余代码
@app.middleware("http")
async def session_middleware(request: Request, call_next):
    response = await call_next(request)
    session = request.cookies.get('session')
    if session:
        response.set_cookie(key='session', value=session, httponly=True)
    return response

2. 修正SessionMiddleware配置

确保会话密钥安全,同时配置正确的cookie属性:

  • 替换硬编码的secret_key为随机生成的密钥(从环境变量读取更安全)
  • 根据环境设置secure属性(生产环境HTTPS下开启,本地测试可关闭)
  • 合理设置max_age和same_site

修改后的配置示例:

import os
import secrets

app.add_middleware(SessionMiddleware, 
                   secret_key=os.getenv("SESSION_SECRET_KEY", secrets.token_hex(32)),
                   max_age=86400,  # 会话有效期1天
                   httponly=True,
                   secure=os.getenv("ENVIRONMENT") == "production",  # 生产环境开启HTTPS
                   same_site="lax")

3. 验证MSAL缓存读写逻辑

检查ad_helpers.py中的load_cache和save_cache实现,确保它们正确操作会话中的缓存数据:

# ad_helpers.py 中正确的缓存读写示例
import msal

def load_cache(request: Request):
    cache = msal.SerializableTokenCache()
    if request.session.get("msal_cache"):
        cache.deserialize(request.session["msal_cache"])
    return cache

def save_cache(request: Request, cache: msal.SerializableTokenCache):
    if cache.has_state_changed:
        request.session["msal_cache"] = cache.serialize()

如果缓存未正确序列化/反序列化,会导致会话中的用户数据无法被后续请求读取。

4. 检查重定向与会话提交

确保在oauth_callback中设置request.session['user']后,会话数据被正确提交:

  • 确认user_info = result.get('id_token_claims')返回有效数据(可通过日志验证)
  • 确认request.session['user']赋值完成后再执行重定向

5. 浏览器端Cookie验证

  1. 完成OAuth回调后,打开浏览器开发者工具(F12),查看Application标签下的Cookies,确认是否存在session cookie
  2. 访问/user-profile时,查看Network标签下的请求头,确认Cookie字段包含session值
  3. 如果Cookie未被携带,检查:
    • 是否在HTTP环境下设置了secure=True(需改为False)
    • same_site设置是否与前端请求模式匹配(跨域场景可尝试same_site="none",但需配合secure=True)
    • 域名是否一致(跨域时需配置domain参数)

6. 临时关闭自动重载测试

如果使用uvicorn --reload运行服务,重载会导致进程重启,会话数据丢失。测试时关闭重载,直接用uvicorn main:app启动服务。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 01:54:53