Flask多用户会话串权求助:用户B登录显示用户A数据
排查解决方案
1. 检查Flask会话核心配置
- 确认生产环境的
SECRET_KEY是唯一随机值,禁止使用开发环境的测试密钥或硬编码固定值。可通过secrets.token_hex(16)生成符合要求的密钥,并通过环境变量注入(而非写死在代码中)。 - 若使用服务器端会话(如
SESSION_TYPE = 'filesystem'),需确保会话存储目录为进程隔离模式,或改用Redis等分布式存储方案,避免多进程共享会话文件导致串号。
2. 排查Flask-Login的实现逻辑
- 禁止使用全局变量存储用户状态,必须使用Flask-Login提供的
from flask_login import current_user代理对象——它与请求上下文绑定,每个请求独立隔离。 - 检查
user_loader加载函数,确保每次请求都从数据库实时查询用户,禁止缓存用户对象:@login_manager.user_loader def load_user(user_id): # 正确实现:每次请求都从数据库获取用户 return User.query.get(int(user_id)) # 错误示例:缓存导致不同请求共享用户 # if not hasattr(load_user, 'cached'): # load_user.cached = User.query.get(int(user_id)) # return load_user.cached - 所有敏感视图必须正确添加
@login_required装饰器,且用户数据均从current_user对象获取,而非全局缓存或其他非上下文变量。
3. 检查生产服务器的WSGI/代理配置
- PythonAnywhere/O2switch:若使用多进程WSGI配置(如uWSGI的
processes参数>1),需确保会话存储不依赖进程内内存或本地文件。优先使用默认的客户端Cookie会话模式,避免进程间状态共享。 - 若服务器启用了反向代理(如Nginx),需禁用动态页面的缓存功能,防止用户B获取到用户A的缓存页面。
4. 添加响应头禁止页面缓存
在用户个人数据等敏感视图中,强制添加禁止缓存的响应头,避免服务器或浏览器缓存用户隐私内容:
from flask import make_response @app.route('/profile') @login_required def profile(): resp = make_response(render_template('profile.html', user=current_user)) resp.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate' resp.headers['Pragma'] = 'no-cache' resp.headers['Expires'] = '0' return resp
内容的提问来源于stack exchange,提问作者Pado
相关产品推荐
相关产品推荐

