Flask会话变量无法跨请求持久化,求问题排查方案
Flask会话无法跨请求持久化的排查与解决
问题描述
按文档配置Flask会话后,先请求/quux接口设置会话值,再请求/接口时返回{ 'message' : 'No session key' },会话未持久化。同时curl生成的cookie文件为空。
复现操作
- 执行curl请求:
$ curl --verbose -X POST http://127.0.0.1:5000/quux --cookie-jar \ cookie.txt -H 'Content-Type: application/json' --data '{ "foo" : "mytest"}' $ curl --verbose -X GET http://127.0.0.1:5000 --cookie-jar \ cookie.txt -H 'Content-Type: application/json'
- 查看cookie文件内容为空:
$ cat cookie.txt # Netscape HTTP Cookie File # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. $
代码示例
from flask import Flask, jsonify, request, session, redirect, after_this_request from flask_cors import CORS, cross_origin app = Flask(__name__) CORS(app) app.config['CORS_HEADERS'] = 'Content-Type' app.secret_key = 'secret' @app.route('/') def home(): if "baz" in session: print("baz is",session['baz']) return jsonify({ 'message': session['baz'] }), 200 return jsonify({ 'message' : 'No session key' }), 400 @app.route('/quux', methods=['POST']) def quux(): data = request.get_json() session['baz'] = data["foo"] # 此处能打印出会话值,但后续请求无法获取 for x in session: print("key is",x," val is",session[x]) return redirect('/', code=302) if __name__ == '__main__': app.run()
问题原因及解决方法
1. curl参数使用错误
第二个curl请求误用了--cookie-jar参数,该参数的作用是将服务器返回的cookie写入文件,而读取已保存的cookie需要使用--cookie参数。
修正后的curl命令:
# 第一步:发送POST请求,保存cookie到cookie.txt curl --verbose -X POST http://127.0.0.1:5000/quux --cookie-jar cookie.txt -H 'Content-Type: application/json' --data '{ "foo" : "mytest"}' # 第二步:发送GET请求,读取cookie.txt中的cookie curl --verbose -X GET http://127.0.0.1:5000 --cookie cookie.txt -H 'Content-Type: application/json'
2. CORS配置未允许携带凭证
启用CORS后,默认跨域请求不会携带cookie,需要修改CORS配置以支持凭证传递:
修改代码中的CORS初始化部分:
# 启用CORS并允许携带凭证 CORS(app, supports_credentials=True) # 更新允许的请求头,包含Cookie app.config['CORS_HEADERS'] = 'Content-Type, Cookie'
同时在路由上添加@cross_origin(supports_credentials=True)注解:
@app.route('/') @cross_origin(supports_credentials=True) def home(): # 原有代码保持不变 @app.route('/quux', methods=['POST']) @cross_origin(supports_credentials=True) def quux(): # 原有代码保持不变
3. 显式标记会话修改(可选)
部分场景下Flask无法自动检测会话修改,可在设置会话值后显式标记:
@app.route('/quux', methods=['POST']) def quux(): data = request.get_json() session['baz'] = data["foo"] # 显式标记会话已修改 session.modified = True # 打印会话值 for x in session: print("key is",x," val is",session[x]) return redirect('/', code=302)
内容的提问来源于stack exchange,提问作者Lucky
相关产品推荐
相关产品推荐

