M2M 组织成员管理接入指南
本文档面向第三方系统对接工程师,介绍如何通过 M2M(Machine-to-Machine)方式接入 Code Bird Cloud 的组织成员管理能力。
如果你的系统以前是通过组织角色名
admin或organization_roles判断“组织管理员”,请先阅读 管理员身份判定迁移说明。当前组织管理员的最新判定方式是成员关系字段is_admin。
读完本文后,你应该可以完成以下事情:
- 理解这套能力的鉴权模型
- 让平台管理员在后台完成必要配置
- 使用
client_credentials + organization_id获取组织级 M2M Token - 调用组织成员查询、创建/加入、移除、角色查询、角色分配接口
- 快速定位常见的
403 / 404 / 500错误
适用场景
适合以下类型的集成:
- 第三方 SaaS 平台同步组织成员到 Code Bird Cloud
- 企业内部系统按组织批量创建、加入或维护成员
- 第三方服务在特定组织上下文中查询成员和组织角色
- 第三方服务根据业务数据自动调整组织成员角色
不适合以下场景:
- 需要用户浏览器参与授权的场景
- 需要邀请制入驻、邮件激活的场景
- 需要第三方直接设置或取消组织管理员的场景
核心概念
1. 用户仍然是平台全局用户
Code Bird Cloud 中的用户不是“组织私有用户”。
同一个用户可以属于多个组织。M2M 创建成员时,本质上是:
- 如果手机号不存在:创建一个平台用户,再加入当前组织
- 如果手机号已存在:直接把已有平台用户加入当前组织
2. 组织管理员是成员关系上的独立标记
组织管理员不是第三方应用可操作的对象。
当前规则是:
- 第三方应用可以查看管理员
- 第三方应用不能移除管理员
- 第三方应用不能设置管理员或取消管理员
- 管理员只能由后台管理员在控制台中维护
3. 组织角色不直接等于权限
M2M 应用在组织里被分配的是“组织角色”,但真正用于鉴权的是这个角色背后绑定的 scope。
你可以这样理解:
- 应用绑定到组织:决定这个应用能不能拿到该组织上下文的 Token
- 给应用分配组织角色:决定这个应用在该组织内具备哪一类身份
- 组织角色绑定 scope:决定这个应用最终能调用哪些 API
鉴权模型
M2M 组织成员管理接口使用组织级 M2M Token。
请求链路
第三方应用
-> 使用 client_credentials + organization_id 请求 Token
-> Code Bird Cloud 校验应用是否绑定到该组织
-> 加载该应用在该组织下的组织角色
-> 从组织角色中解析 scope
-> 返回带 organization_id 的 M2M Token
-> 第三方应用携带 Bearer Token 调用 /api/v1/m2m/organizations/:organizationId/members...
-> 服务端校验 token_type、organization_id、scopeM2M 成员接口的放行条件
请求必须同时满足:
- Token 为 M2M Token,即
token_type = "m2m" - Token 内包含
organization_id - Token 中的
organization_id必须等于 URL 路径里的organizationId - Token scope 必须包含以下任一项:
manage:organizationsall
说明:组织级 M2M token 的
scope和aud由“该应用在该组织下的组织角色”动态解析生成。 如果拿到的 token 中缺少这两个字段,优先检查组织绑定、应用角色分配和角色权限配置是否已正确保存。
其中:
manage:organizations来自组织 Scopeall来自 Management API Resource Scope
也就是说,这组 API 同时兼容两种组织级 Token:
- 路径 A:组织 Scope Token
- 路径 B:组织级 API 资源 Token
如果你只接这套组织成员管理接口,推荐优先使用路径 B:组织级 API 资源 Token,因为它更接近标准的 API 资源授权模型。
接入前准备
在第三方工程师调用接口前,平台管理员需要先完成后台配置。
方案一:通过管理后台配置
第 1 步:创建 M2M 应用
在「应用管理」中创建一个类型为 MachineToMachine 的应用,并保存:
- Client ID
- Client Secret
第 2 步:准备组织角色模板
在「组织模板」中创建或选择一个组织角色模板。
例如可以创建一个叫 org-member-manager 的角色模板。
第 3 步:给组织角色模板分配权限
有两种方式:
- 方式 A:给组织角色绑定组织 Scope
manage:organizations - 方式 B:给组织角色绑定 Management API 资源 Scope
all
如果你要调用本文档中的 /api/v1/m2m/organizations/... 接口,至少需要其中一种。
第 4 步:将 M2M 应用绑定到目标组织
在「组织 -> 编辑组织 -> 机器对机器应用」中绑定目标应用。
第 5 步:给这个组织内的应用分配组织角色
仍在「组织 -> 编辑组织 -> 机器对机器应用」中,给该应用分配上一步准备好的组织角色。
只有做到这一步,请求 Token 时系统才会把对应 scope 放进 Token。
方案二:通过后台管理 API 预配置
如果你不通过控制台,也可以用管理 API 完成配置。
常用接口如下:
| 目的 | 接口 |
|---|---|
| 创建组织角色模板 | POST /api/v1/organization-roles |
| 给组织角色分配组织 Scope | PUT /api/v1/organization-roles/{id}/scopes |
| 给组织角色分配 API 资源 Scope | PUT /api/v1/organization-roles/{id}/resource-scopes |
| 绑定应用到组织 | POST /api/v1/organizations/{id}/applications |
| 给组织中的应用分配组织角色 | PUT /api/v1/organizations/{id}/applications/{appId}/roles |
这些接口需要管理员 Token,详细说明可结合以下文档阅读:
第一步:获取组织级 M2M Token
Token 端点:
POST /oidc/token
Content-Type: application/x-www-form-urlencoded推荐方式:组织级 API 资源 Token
推荐请求:
grant_type=client_credentials&
client_id=YOUR_CLIENT_ID&
client_secret=YOUR_CLIENT_SECRET&
organization_id=ORG_ID&
resource=urn:codebird:management-api:YOUR_TENANT_ID
resource必须传当前租户下真实存在的 Management API Resource Indicator。 可以直接从后台「授权 -> API 资源 -> Code Bird Management API」页面复制,格式通常为urn:codebird:management-api:YOUR_TENANT_ID。
兼容方式:组织 Scope Token
如果你的组织角色绑定的是 manage:organizations 这类组织 Scope,也可以不传 resource:
grant_type=client_credentials&
client_id=YOUR_CLIENT_ID&
client_secret=YOUR_CLIENT_SECRET&
organization_id=ORG_IDcURL 示例
export BASE_URL="https://your-domain.com"
export CLIENT_ID="YOUR_CLIENT_ID"
export CLIENT_SECRET="YOUR_CLIENT_SECRET"
export ORG_ID="BxBgwQhpjDmtMpsLojRuj"
export RESOURCE="urn:codebird:management-api:YOUR_TENANT_ID"
ACCESS_TOKEN=$(curl -s -X POST "${BASE_URL}/oidc/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=${CLIENT_ID}" \
-d "client_secret=${CLIENT_SECRET}" \
-d "organization_id=${ORG_ID}" \
-d "resource=${RESOURCE}" | jq -r '.access_token')
echo "${ACCESS_TOKEN}"成功响应示例
{
"access_token": "eyJhbGciOiJFUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "all"
}Token 关键 Claims
{
"sub": "JU_9INRc_cyTtDDw0U2dD",
"client_id": "JU_9INRc_cyTtDDw0U2dD",
"token_type": "m2m",
"organization_id": "BxBgwQhpjDmtMpsLojRuj",
"aud": ["urn:codebird:management-api:YOUR_TENANT_ID"],
"scope": ["all"]
}关键字段说明:
| Claim | 说明 |
|---|---|
token_type | 固定为 m2m |
organization_id | 当前 Token 所属组织 |
scope | 从“该应用在该组织下的组织角色”推导出来 |
aud | 如果传了 resource,这里就是该资源标识 |
第二步:调用组织成员管理 API
接口基准路径:
/api/v1/m2m/organizations/{organizationId}/members统一请求头:
Authorization: Bearer <access_token>
Content-Type: application/json统一成功响应格式:
{
"code": 0,
"result": {},
"message": "success"
}统一失败响应格式:
{
"code": 41305,
"result": null,
"message": "组织管理员不允许由第三方应用移除"
}API 1:查询组织成员列表
GET /api/v1/m2m/organizations/{organizationId}/members
分页查询当前组织下的成员。
查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
page | integer | 否 | 页码,默认 1 |
page_size | integer | 否 | 每页条数,默认 20 |
phone | string | 否 | 按手机号精确筛选 |
name | string | 否 | 按姓名模糊筛选 |
is_admin | boolean | 否 | 按管理员标记筛选 |
cURL 示例
curl -X GET "${BASE_URL}/api/v1/m2m/organizations/${ORG_ID}/members?page=1&page_size=20&is_admin=false" \
-H "Authorization: Bearer ${ACCESS_TOKEN}"成功响应示例
{
"code": 0,
"message": "success",
"result": {
"total": 2,
"data": [
{
"id": "_J4OiutDpPy_zl0kqNC_x",
"username": "alice",
"primary_phone": "13800000001",
"primary_email": "alice@example.com",
"name": "Alice",
"is_admin": false,
"joined_at": "2026-03-12T10:00:00Z",
"created_at": "2026-03-12T10:00:00Z"
}
],
"page": 1,
"page_size": 20
}
}字段说明
| 字段 | 说明 |
|---|---|
id | 平台用户 ID |
username | 用户名,可能为空 |
primary_phone | 用户主手机号 |
primary_email | 用户主邮箱,可能为空 |
name | 用户姓名 |
is_admin | 是否为组织管理员 |
joined_at | 加入当前组织的时间 |
created_at | 用户创建时间 |
API 2:按手机号创建或加入组织成员
POST /api/v1/m2m/organizations/{organizationId}/members
按手机号创建平台用户,或者复用已有平台用户并加入当前组织。
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
phone | string | 是 | 用户手机号,作为主判定键 |
name | string | 否 | 用户姓名 |
email | string | 否 | 用户邮箱,非主判定键 |
行为规则
- 如果手机号不存在:创建新用户并加入当前组织
- 如果手机号已存在:直接把该用户加入当前组织
- 如果该用户已经在当前组织:接口仍返回成功
cURL 示例
curl -X POST "${BASE_URL}/api/v1/m2m/organizations/${ORG_ID}/members" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"phone": "13800000002",
"name": "Bob",
"email": "bob@example.com"
}'成功响应示例
{
"code": 0,
"message": "success",
"result": {
"id": "user_bob_xxx",
"username": "bob",
"primary_phone": "13800000002",
"primary_email": "bob@example.com",
"name": "Bob",
"is_admin": false,
"joined_at": "2026-03-12T10:02:00Z",
"created_at": "2026-03-12T10:02:00Z"
}
}第三方如需判断当前组织中的特殊成员,请仅使用
is_admin。 该字段表示“当前组织管理员”,不等同于平台后台超级管理员。
API 3:移除组织成员
DELETE /api/v1/m2m/organizations/{organizationId}/members/{userId}
移除当前组织中的一个普通成员,同时清除该成员在本组织内的组织角色分配。
cURL 示例
curl -X DELETE "${BASE_URL}/api/v1/m2m/organizations/${ORG_ID}/members/${USER_ID}" \
-H "Authorization: Bearer ${ACCESS_TOKEN}"成功响应示例
{
"code": 0,
"message": "success",
"result": null
}限制
- 不能移除组织管理员
- 只能移除当前组织中的成员
- 不会删除平台用户本身,只会删除该用户与当前组织的关系
API 4:查询成员在当前组织内的角色
GET /api/v1/m2m/organizations/{organizationId}/members/{userId}/roles
查询某个成员在当前组织中的角色列表。
cURL 示例
curl -X GET "${BASE_URL}/api/v1/m2m/organizations/${ORG_ID}/members/${USER_ID}/roles" \
-H "Authorization: Bearer ${ACCESS_TOKEN}"成功响应示例
{
"code": 0,
"message": "success",
"result": [
{
"id": "role_member_manager",
"name": "member-manager",
"description": "Can manage organization members",
"type": "User",
"created_at": "2026-03-01T08:00:00Z"
}
]
}API 5:替换成员在当前组织内的角色
PUT /api/v1/m2m/organizations/{organizationId}/members/{userId}/roles
全量替换成员在当前组织中的角色分配。
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
role_ids | string[] | 是 | 组织角色 ID 列表 |
cURL 示例
curl -X PUT "${BASE_URL}/api/v1/m2m/organizations/${ORG_ID}/members/${USER_ID}/roles" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"role_ids": ["role_member_manager", "role_viewer"]
}'成功响应示例
{
"code": 0,
"message": "success",
"result": null
}行为说明
- 这是“替换”而不是“增量追加”
- 新列表会覆盖该成员在当前组织中的旧角色列表
- 不会影响该用户在其他组织中的角色
推荐接入流程
建议第三方系统按以下顺序实现:
- 平台管理员完成 M2M 应用、组织角色、scope、组织绑定配置
- 第三方系统调用
/oidc/token获取组织级 M2M Token - 调用成员列表接口确认当前组织成员现状
- 如需新增成员,调用“按手机号创建或加入组织成员”
- 如需调整角色,调用成员角色查询与角色替换接口
- 如需移除成员,先确认该成员不是管理员,再调用删除接口
常见错误与排查
1. 403 应用未绑定到该组织
说明请求 Token 时,M2M 应用还没有绑定到该组织。
检查:
- 后台是否已将该应用绑定到目标组织
organization_id是否填写正确
2. 403 组织上下文不匹配
说明 Token 里的 organization_id 与 URL 里的 {organizationId} 不一致。
检查:
- 申请 Token 时传入的
organization_id - 调用 API 时的路径参数
3. 403 权限不足
说明当前 Token 虽然是组织级 Token,但 scope 不够。
检查:
- 该应用在该组织下是否分配了组织角色
- 该组织角色是否绑定了
manage:organizations - 或该组织角色是否绑定了 Management API 的
all资源 scope
4. 403 组织管理员不允许由第三方应用移除
说明目标成员是组织管理员。
处理方式:
- 先由后台管理员在控制台调整管理员身份
- 或跳过该成员,不通过第三方接口移除
5. 404 组织不存在
说明路径里的组织 ID 不存在。
6. 404 组织成员不存在
说明目标用户不在该组织下,或者 userId 写错。
错误码参考
M2M 组织成员接口错误码
| 错误码 | HTTP 状态 | 说明 |
|---|---|---|
41300 | 500 | 获取组织成员列表失败 |
41301 | 404 | 组织成员不存在 |
41302 | 500 | 创建或加入组织成员失败 |
41303 | 500 | 移除组织成员失败 |
41304 | 500 | 分配组织成员角色失败 |
41305 | 403 | 组织管理员不允许由第三方应用移除 |
组织相关通用错误码
| 错误码 | HTTP 状态 | 说明 |
|---|---|---|
41000 | 404 | 组织不存在 |
鉴权层常见错误消息
| HTTP 状态 | 消息 |
|---|---|
403 | 仅支持机器对机器应用访问 |
403 | 组织上下文不匹配 |
403 | 权限不足 |
最小可运行示例
下面是一个典型的自动同步流程:
#!/usr/bin/env bash
set -euo pipefail
BASE_URL="https://your-domain.com"
CLIENT_ID="YOUR_CLIENT_ID"
CLIENT_SECRET="YOUR_CLIENT_SECRET"
ORG_ID="BxBgwQhpjDmtMpsLojRuj"
RESOURCE="urn:codebird:management-api:YOUR_TENANT_ID"
PHONE="13800000003"
NAME="Charlie"
ACCESS_TOKEN=$(curl -s -X POST "${BASE_URL}/oidc/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=${CLIENT_ID}" \
-d "client_secret=${CLIENT_SECRET}" \
-d "organization_id=${ORG_ID}" \
-d "resource=${RESOURCE}" | jq -r '.access_token')
MEMBER=$(curl -s -X POST "${BASE_URL}/api/v1/m2m/organizations/${ORG_ID}/members" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"phone\":\"${PHONE}\",\"name\":\"${NAME}\"}")
USER_ID=$(echo "${MEMBER}" | jq -r '.result.id')
curl -s -X PUT "${BASE_URL}/api/v1/m2m/organizations/${ORG_ID}/members/${USER_ID}/roles" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"role_ids":["role_member_manager"]}'与其他文档的关系
建议按这个顺序阅读:
- M2M 认证指南
- M2M 组织级 Token
- 本文档:组织成员管理接入
- Management API 交互
- 组织管理 API
