Odoo API 登录认证与 session_id 获取全攻略
本文详细介绍如何通过 API 方式模拟登录 Odoo,正确获取 session_id,并在自动化测试、接口开发、第三方集成等场景下安全高效地使用 Odoo 的认证机制。适合 Odoo 开发者、测试工程师、自动化运维等技术人员参考。
目录
- 背景说明
- Odoo 推荐登录接口与原理
- 标准 API 请求配置(以 Apipost 为例)
- session_id 获取机制详解
- 常见问题与排查
- Python requests 自动化登录示例
- Apipost 导入文件说明
- 最佳实践与安全建议
- FAQ
- 总结
背景说明
Odoo 是一套功能强大的开源 ERP/CRM 系统,支持通过 Web API 进行认证和数据操作。许多开发者在使用 Apipost、Postman、Python requests 等工具模拟登录时,常常遇到一个困惑:登录成功后响应体中没有 session_id 字段,导致后续接口调用失败。
实际上,Odoo 的 session_id 并不在 JSON 响应体中返回,而是通过 HTTP 响应头的 Set-Cookie 字段传递。理解这一机制是成功进行 Odoo API 开发的关键。
Odoo 推荐登录接口与原理
接口选择
- 推荐接口:
/web/session/authenticate(JSON-RPC 格式) - 不推荐接口:
/web/login(需要 CSRF token,主要用于 Web 表单)
认证流程
- 发送登录请求:客户端向
/web/session/authenticate发送 POST 请求,Body 为 JSON 格式,包含数据库名、用户名、密码 - 服务器验证:Odoo 验证用户凭据,成功后在响应头
Set-Cookie中设置session_id - 会话维持:客户端提取
session_id,在后续所有 API 请求的Cookie头中携带该值
标准 API 请求配置(以 Apipost 为例)
请求基本信息
- URL:
http://your-odoo-domain/web/session/authenticate - Method:
POST - Headers:
Content-Type: application/json - Body 类型:Raw,选择 JSON 格式
请求 Body 示例
{
"jsonrpc": "2.0",
"method": "call",
"params": {
"db": "your_database_name",
"login": "your_username",
"password": "your_password"
}
}
⚠️ 重要提示:请将上述示例中的占位符替换为实际值:
your_database_name:Odoo 数据库名称(如:odoo_production)your_username:登录用户名your_password:登录密码
成功响应示例
{
"jsonrpc": "2.0",
"id": null,
"result": {
"uid": 2,
"is_system": false,
"is_admin": true,
"user_context": {
"lang": "zh_CN",
"tz": "Asia/Shanghai"
},
"username": "admin",
"name": "Administrator"
}
}

session_id 获取机制详解
关键概念
- 响应体:包含用户信息,但不包含
session_id字段 - 响应头:
Set-Cookie字段中包含session_id - 后续请求:必须在
Cookie头中携带session_id
响应头示例
HTTP/1.1 200 OK
Content-Type: application/json
Set-Cookie: session_id=abc123def456; Path=/; HttpOnly; SameSite=Lax
Apipost 自动提取 session_id 方法
- 手动查看:在响应的「Headers」标签页中查找
Set-Cookie - 自动提取:在「Tests」标签页添加以下脚本:
// 提取 session_id 并保存到环境变量
const setCookie = pm.response.headers.get('Set-Cookie');
if (setCookie) {
const match = setCookie.match(/session_id=([^;]+)/);
if (match) {
pm.environment.set('session_id', match[1]);
console.log('session_id 已保存:', match[1]);
} else {
console.log('未找到 session_id');
}
} else {
console.log('响应头中没有 Set-Cookie');
}
- 使用变量:在后续请求的 Headers 中添加:
Cookie: session_id={{session_id}}
常见问题与排查
Q1: 响应体中没有 session_id 字段?
解答:这是正常现象。session_id 位于响应头的 Set-Cookie 中,不在 JSON 响应体内。
Q2: 响应头中没有 Set-Cookie?
可能原因及解决方案:
- 检查请求方法是否为
POST - 确认
Content-Type为application/json - 验证数据库名、用户名、密码是否正确
- 检查 Odoo 服务器的 CORS 配置
- 确认 Odoo 服务运行正常
Q3: 登录失败的响应示例
{
"jsonrpc": "2.0",
"id": null,
"result": {
"uid": false,
"error": "Access Denied"
}
}
Q4: 后续请求提示 session 失效?
排查步骤:
- 确认
Cookie头格式正确:Cookie: session_id=xxx - 检查 session 是否已过期
- 验证 Odoo 配置的 session 超时时间
- 确认没有多次登录导致 session 冲突
Python requests 自动化登录示例
以下代码适用于自动化脚本、接口测试、系统集成等场景:
import requests
import re
def odoo_login(base_url, database, username, password):
"""
Odoo 登录函数
Args:
base_url (str): Odoo 服务器地址,如 'http://localhost:8069'
database (str): 数据库名称
username (str): 用户名
password (str): 密码
Returns:
tuple: (session_id, user_info) 或 (None, error_message)
"""
login_url = f"{base_url}/web/session/authenticate"
payload = {
"jsonrpc": "2.0",
"method": "call",
"params": {
"db": database,
"login": username,
"password": password
}
}
headers = {"Content-Type": "application/json"}
try:
# 发送登录请求
response = requests.post(login_url, json=payload, headers=headers, timeout=30)
response.raise_for_status()
# 检查业务逻辑错误
result = response.json().get('result', {})
if not result.get('uid'):
return None, f"登录失败: {result.get('error', '用户名或密码错误')}"
# 提取 session_id
session_id = None
set_cookie = response.headers.get('Set-Cookie')
if set_cookie:
match = re.search(r'session_id=([^;]+)', set_cookie)
if match:
session_id = match.group(1)
if not session_id:
return None, "未能获取 session_id"
return session_id, result
except requests.exceptions.RequestException as e:
return None, f"请求异常: {str(e)}"
except Exception as e:
return None, f"未知错误: {str(e)}"
def odoo_api_call(base_url, session_id, model, method, args=None, kwargs=None):
"""
调用 Odoo API
Args:
base_url (str): Odoo 服务器地址
session_id (str): 会话ID
model (str): 模型名称,如 'res.partner'
method (str): 方法名称,如 'search_read'
args (list): 位置参数
kwargs (dict): 关键字参数
Returns:
dict: API 响应结果
"""
api_url = f"{base_url}/web/dataset/call_kw/{model}/{method}"
headers = {
"Content-Type": "application/json",
"Cookie": f"session_id={session_id}"
}
payload = {
"jsonrpc": "2.0",
"method": "call",
"params": {
"model": model,
"method": method,
"args": args or [],
"kwargs": kwargs or {}
}
}
response = requests.post(api_url, json=payload, headers=headers, timeout=30)
response.raise_for_status()
return response.json()
# 使用示例
if __name__ == "__main__":
# 配置参数
BASE_URL = "http://your-odoo-domain"
DATABASE = "your_database_name"
USERNAME = "your_username"
PASSWORD = "your_password"
# 登录
session_id, user_info = odoo_login(BASE_URL, DATABASE, USERNAME, PASSWORD)
if session_id:
print(f"登录成功!session_id: {session_id}")
print(f"用户信息: {user_info}")
# 调用 API 示例:获取前5个合作伙伴
try:
result = odoo_api_call(
BASE_URL,
session_id,
'res.partner',
'search_read',
kwargs={
"fields": ["id", "name", "email"],
"limit": 5
}
)
print("API 调用结果:", result)
except Exception as e:
print(f"API 调用失败: {e}")
else:
print(f"登录失败: {user_info}")
Apipost 导入文件说明
导出方法
- 在 Apipost 中配置好登录请求
- 点击右上角「导出」按钮
- 选择「导出为 JSON」或「导出为 Collection」
团队共享
- 生成的配置文件可在团队内共享
- 支持环境变量,便于在不同环境间切换
- 如需定制化的 Apipost 配置文件,可提供具体需求
最佳实践与安全建议
开发实践
- 接口选择:优先使用
/web/session/authenticate,避免使用/web/login - 错误处理:完善登录失败、网络异常、session 过期等异常处理
- 自动化:使用变量或代码自动管理
session_id,避免手动复制粘贴 - 重试机制:在 session 失效时自动重新登录
安全建议
- HTTPS:生产环境务必使用 HTTPS,防止 session 被截获
- 凭据管理:不要在代码中硬编码用户名密码,使用环境变量或配置文件
- 权限控制:为 API 调用创建专用用户,分配最小必要权限
- 会话管理:定期检查 session 生命周期配置,避免过长或过短
- 日志审计:记录 API 调用日志,便于问题排查和安全审计
FAQ
Q: Odoo 支持其他认证方式吗?
A: 社区版主要支持 session 认证。企业版和某些插件支持 OAuth2、API Key、JWT 等方式,具体可查阅官方文档或插件说明。
Q: 可以用 Postman、curl 等工具测试吗?
A: 当然可以。原理相同,关键是从响应头提取 Set-Cookie 并在后续请求中携带。
Q: session_id 的有效期是多长?
A: 默认情况下,Odoo session 的有效期较长(通常几小时到几天),具体取决于服务器配置。可在 Odoo 配置文件中调整。
Q: 如何处理并发登录问题?
A: Odoo 支持同一用户多次登录,每次登录会生成新的 session_id。建议在应用中维护 session 池或使用连接池。
Q: 忘记携带 session_id 会怎样?
A: 大多数 API 会返回认证错误,提示需要登录。具体错误信息可能是 "Access Denied" 或 "Session expired"。
总结
本文详细介绍了 Odoo API 登录认证的完整流程,重点解析了 session_id 的获取和使用机制。关键要点包括:
- 核心机制:
session_id在响应头Set-Cookie中,不在 JSON 响应体内 - 工具支持:Apipost、Postman、Python requests 等都可实现自动化登录
- 问题排查:重点检查请求参数、响应头、CORS 设置等
- 最佳实践:自动化 session 管理,完善错误处理,注意安全防护

浙公网安备 33010602011771号