Flask同浏览器下每次请求新建Session问题求助
问题根源与解决方案
你的核心问题是浏览器没有在后续请求中携带Flask的Session Cookie,导致每次请求都会触发Flask新建会话,无法保留access_token和refresh_token。以下是具体原因和修复步骤:
1. 统一前后端域名(localhost/127.0.0.1 不一致)
浏览器会把localhost和127.0.0.1视为不同域名,导致Cookie无法跨域名传递:
- 前端
loginSpotify函数中的请求地址改为http://localhost:5001/spotify_login(和后端回调、客户端重定向地址统一用localhost) - 后端的
REDIRECT_URI和CLIENT_REDIRECT保持用localhost,不要混用127.0.0.1
2. 配置CORS允许携带Credentials
Flask-CORS默认不允许跨域请求携带Cookie,需要修改CORS配置:
# 替换原来的CORS(app) CORS(app, supports_credentials=True)
如果后续前端用fetch/axios调用后端接口(比如/is_logged_in),需要在请求中添加凭证配置:
- Fetch:
fetch(url, { credentials: 'include' }) - Axios:
axios.get(url, { withCredentials: true })
3. 修正Flask Session的Cookie参数
默认的Session Cookie配置在跨域场景下会被浏览器拦截,添加以下配置到Flask app:
app.config.update( SESSION_COOKIE_SAMESITE='Lax', # 开发环境用Lax,生产环境HTTPS下可设为None SESSION_COOKIE_SECURE=False, # 开发环境设为False,生产环境HTTPS必须设为True SESSION_COOKIE_DOMAIN='localhost' # 统一域名,确保Cookie能被正确传递 )
注意:如果生产环境用HTTPS,
SESSION_COOKIE_SAMESITE要设为'None',同时SESSION_COOKIE_SECURE必须为True,这是浏览器的安全要求。
4. 修复OAuth回调中的状态验证逻辑
你代码中的状态判断逻辑错误,and会导致只有当state为None且不等于会话中的state时才跳转错误页,这完全不符合预期,应该改为or:
# 替换原来的判断 if state is None or state != session['state']: return redirect('/#?error=state_mismatch')
5. 验证修改后的流程
修改完成后,重新启动服务:
- 点击前端登录按钮,跳转到Spotify授权页
- 授权完成后,回调到Flask的
/callback,此时会话中会保存access_token和refresh_token - 前端调用
/is_logged_in时,浏览器会自动携带Session Cookie,Flask就能读取到会话中的token
补充说明
从你打印的日志可以看到,最后一次请求/is_logged_in时,request.cookies是空的,说明浏览器没有把之前设置的Session Cookie传回后端,这就是会话重建的直接原因。通过上述步骤统一域名、配置CORS和Session Cookie参数,就能解决这个问题。
内容的提问来源于stack exchange,提问作者Evan G
相关产品推荐
相关产品推荐

