服务器间认证 API
Melody Auth 服务器间认证 API 为服务器应用提供管理资源的能力。
快速开始
首先,通过在 Basic Auth 头中使用 clientId 和 clientSecret,向 /token 端点获取 access_token。
随后,在后续请求的 Authorization 头中,以 Bearer 令牌的形式携带该 access_token。
- HTTP 方法:
POST - Content-Type:
application/x-www-form-urlencoded - URL:
[melody_auth_server_url]/oauth2/v1/token
Token 请求参数
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
grant_type | 'client_credentials' | 是 | 指定使用 client_credentials 模式交换令牌 |
scope | string | 是 | 需要申请的权限作用域(如:read_user write_user) |
Token 请求示例
const credentials = `${clientId}:${clientSecret}`;
const encodedCredentials = Buffer.from(credentials).toString('base64');
const data = {
grant_type: 'client_credentials',
scope: 'read_user write_user',
}
const urlEncodedData = new URLSearchParams(data).toString()
fetch('/oauth2/v1/token', {
method: 'POST',
headers: {
'Content-type': 'application/x-www-form-urlencoded',
'Authorization': `basic ${encodedCredentials}`
},
body: urlEncodedData,
})
Token 响应示例
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMzQ1NiIsInNjb3BlIjoicmVhZF91c2VyIHdyaXRlX3VzZXIiLCJpYXQiOjE3MjE0MjE4MTcsImV4cCI6MTcyMTQyNTQxN30.blhriLgm67tkL89tVLdeNN5nl4EUssy6FIfp4kTOlqM",
"expires_in": 3600,
"expires_on": 1721425417,
"token_type": "Bearer",
"scope": "read_user write_user"
}
系统信息
/info 端点会返回当前服务器配置值,包括功能开关和面向客户端的配置。由于这些信息可能暴露安全策略和部署细节,该端点需要有效的服务器间访问令牌,但不要求任何特定作用域。
- HTTP 方法:
GET - URL:
[melody_auth_server_url]/info - 必需作用域:无
- Authorization:
Bearer [access_token]
作用域
服务器间令牌被授予的作用域决定了它可以调用哪些端点。每个端点所需的作用域可在 REST API Swagger 中查看。root 作用域可访问所有端点。
分配 root 作用域
在创建应用(POST /api/v1/apps)或更新应用(PUT /api/v1/apps/{id})时,只有自身令牌持有 root 作用域的调用方才能分配 root 作用域。不具备 root 的 write_app 令牌仍可管理其他作用域,但任何在应用作用域列表中包含 root 的请求都会被拒绝,返回 400 以及消息 Only an app with the root scope can assign the root scope to an app。这可以防止 write_app 令牌将自身权限提升为 root。
为 S2S 应用分配作用域
颁发给 S2S 应用的令牌可以使用该应用持有的全部作用域调用 S2S API。为防止 write_app 令牌创建权限更高的应用(例如持有 write_user 或 write_org 的应用),自身令牌不具备 root 的调用方只能为 S2S 应用分配其令牌已持有的作用域。该限制适用于创建 S2S 应用(POST /api/v1/apps)以及为其添加作用域(PUT /api/v1/apps/{id})。更新时只检查新增的作用域,因此调用方可以保留或移除应用已有的作用域。分配其他作用域的请求会被拒绝,返回 400 以及消息 An app without the root scope can only assign scopes it holds to an s2s app。SPA 应用不受影响,因为 SPA 令牌无法调用 S2S API。
默认管理面板应用
管理面板通过默认的 Admin Panel (SPA) 应用(ID 1)让超级管理员登录,并通过默认的 Admin Panel (S2S) 应用(ID 2)调用 API。颁发给这两个应用的令牌都拥有完整的管理权限。例如,能够向 SPA 应用添加自己重定向 URI 的调用方就可以拿到超级管理员的授权码。因此,只有自身令牌持有 root 的调用方才能更新(PUT /api/v1/apps/{id})或删除(DELETE /api/v1/apps/{id})这两个应用。不具备 root 的 write_app 令牌会被拒绝,返回 400 以及消息 Only an app with the root scope can update or delete a default admin panel app。其他应用不受影响。
内置作用域
S2sConfig.builtInScopes 中的内置作用域名称为保留且不可更改:openid、profile、offline_access、root、read_user、write_user、read_app、write_app、read_role、write_role、read_scope、write_scope、read_org 和 write_org。POST /api/v1/scopes 不能创建这些作用域,DELETE /api/v1/scopes/{id} 也不能删除它们。PUT /api/v1/scopes/{id} 可以更新内置作用域的说明或本地化标签,但不能重命名内置作用域,也不能将自定义作用域重命名为内置作用域名称。受限请求会返回 400,并附带消息 Built-in scopes cannot be created, deleted, or renamed。
角色
角色被分配给用户,可在更新用户(PUT /api/v1/users/{authId})或邀请用户(POST /api/v1/users/invitations)时进行管理。两者都需要 write_user 作用域。
内置角色
包括 super_admin 在内的内置角色在 S2sConfig.builtInRoles 中配置。内置角色记录不能通过角色 API 创建、更新或删除;受限请求会返回 400,并附带消息 Built-in roles cannot be created, deleted, or updated。授权使用这些不可变的角色名称。
分配特权角色
内置角色会授予跨应用的提升信任——例如,super_admin 是用于控制用户模拟(impersonation)的角色。为防止 write_user 令牌提升权限(无论是自身还是其他用户的权限),只有自身令牌持有 root 作用域的调用方才能分配特权角色。不具备 root 的 write_user 令牌仍可分配非特权角色,但任何包含特权角色(例如 super_admin)的请求都会被拒绝,返回 400 以及消息 Only an app with the root scope can assign a privileged role。
详细文档
更多信息请参阅 REST API Swagger。