Flask调用login_user后如何从响应中获取Set-Cookie头的加密会话cookie
问题原因
Flask 默认会在所有 after_request 钩子执行完毕后,才会将内存中的 session 对象序列化为签名字符串,写入响应的 Set-Cookie 头中。所以你在 after_request 中读取响应头时,session 对应的 Cookie 还没有被写入,自然只能拿到空列表。
另外你示例代码中的 user_loader 实现不符合规范:Flask-Login 要求 user_loader 回调返回 User 类实例,而你的代码直接调用类方法返回ID,实际运行会报错,需要先修正。
解决方案
方法1:手动触发session保存(最便捷)
你可以主动调用 Flask 内置的 session 保存逻辑,将 session 提前写入响应头,之后就能正常读取 Cookie 了。修改后的完整代码如下:
from flask import Flask, session from flask_login import LoginManager, login_user, UserMixin app = Flask(__name__) login_manager = LoginManager(app) app.config["SECRET_KEY"] = "abcd" class User(UserMixin): def __init__(self, identificator): self.identificator = identificator def get_id(self) -> int: return int(self.identificator) # 修正user_loader实现 @login_manager.user_loader def load_user(user_id): return User(int(user_id)) @app.after_request def ar(resp): # 手动将session写入响应头 app.session_interface.save_session(app, resp, session) # 此时可正常读取Set-Cookie print(resp.headers.getlist("Set-Cookie")) return resp @app.route("/test") def test(): user = User(1234) login_user(user) return "something" if __name__ == "__main__": app.run(debug=True)
方法2:使用request_finished信号
如果不想改动原有 after_request 逻辑,也可以监听 Flask 提供的 request_finished 信号,该信号会在响应完全准备完成、所有响应头都设置完毕后触发,此时可以直接拿到完整的 Set-Cookie 内容:
from flask import request_finished # 注册信号回调 def handle_request_finished(sender, response, **extra): print(response.headers.getlist("Set-Cookie")) request_finished.connect(handle_request_finished, app)
两种方案都可以拿到和 curl -v 输出完全一致的签名session Cookie。
内容的提问来源于stack exchange,提问作者onyxcherry
相关产品推荐
相关产品推荐

