如何在Odoo v10中查找单个用户所有会话并通过Python批量注销
在Odoo v10中查询并注销单个用户的所有会话
一、先搞懂Odoo v10的会话存储逻辑
Odoo v10默认把会话存在本地文件系统里,默认路径是odoo/sessions(具体路径可以看你配置里的session_store项)。每个会话对应一个以会话ID命名的文件,文件内容是序列化后的Python对象,里面的uid字段就是关联用户的数据库ID——这就是我们区分用户会话的核心依据。
二、查询指定用户的所有会话
我们可以遍历会话目录下的所有文件,反序列化每个会话对象,检查uid是否匹配目标用户ID,就能筛选出该用户的所有会话。直接上代码:
import os import pickle from odoo.tools.config import config def get_user_sessions(user_id): # 获取会话存储目录,没配置的话用默认路径 session_dir = config.get('session_dir', './sessions') user_sessions = [] if not os.path.exists(session_dir): return user_sessions # 挨个遍历会话文件 for filename in os.listdir(session_dir): file_path = os.path.join(session_dir, filename) if os.path.isfile(file_path): try: # 反序列化会话对象 with open(file_path, 'rb') as f: session = pickle.load(f) # 匹配目标用户的uid if session.get('uid') == user_id: user_sessions.append({ 'session_id': filename, 'session_data': session, 'file_path': file_path }) except Exception as e: # 遇到损坏的会话文件直接跳过 print(f"读取会话文件 {filename} 出错: {str(e)}") continue return user_sessions
用的时候直接传用户ID就行:
# 替换成你要查询的用户数据库ID target_user_id = 1 user_sessions = get_user_sessions(target_user_id) print(f"找到用户 {target_user_id} 的 {len(user_sessions)} 个会话") for sess in user_sessions: print(f"会话ID: {sess['session_id']}")
三、一次性注销该用户的所有会话
注销的核心就是删掉对应的会话文件——毕竟本地存储的会话,文件没了,用户的会话也就失效了。我们基于上面的查询函数扩展一个注销函数:
def logout_user_all_sessions(user_id): user_sessions = get_user_sessions(user_id) deleted_count = 0 for sess in user_sessions: try: os.remove(sess['file_path']) deleted_count += 1 print(f"已删除会话: {sess['session_id']}") except Exception as e: print(f"删除会话 {sess['session_id']} 失败: {str(e)}") print(f"成功注销用户 {user_id} 的 {deleted_count} 个会话")
调用示例:
logout_user_all_sessions(target_user_id)
几个要注意的点
- 确保执行代码的进程有会话目录的读写权限,不然会出现文件操作失败的情况。
- 如果你用的不是本地文件存储会话(比如配置了Redis),上面的代码就得调整,但你说的是本地文件夹,所以完全适用。
pickle反序列化有安全风险,一定要在可信的服务器环境里执行,别让恶意文件混进会话目录。
内容的提问来源于stack exchange,提问作者Vishnu m nair
相关产品推荐
相关产品推荐

