灵智玫瑰园开放平台向外部应用开放平台的部分能力。当前开放的能力为 身份与授权服务(OAuth 2.0 / OpenID Connect),后续将逐步开放其他服务(如内容 API)。本站按服务分组组织文档,每项服务占一个分组;新服务上线时会在侧栏新增对应分组,现有文档结构不受影响。
身份与授权服务#
身份与授权服务把本平台作为 OAuth 2.0 / OIDC 身份提供方(IdP) 对外提供。平台上的任意"群"(小组)都可以接入一个第三方应用:群创建者在平台侧登记应用,群成员用平台账号登录该应用,平台在授权时向应用声明"用户是谁、是否属于该群、在群里是什么应用成员组"。应用不接触平台的课程、帖子等业务数据,只获得经过用户授权的身份与群组信息。
该服务解决的核心问题是身份不互通:没有它,每个外部应用各自维护一套账号与成员名单,群管理员需要在多个系统重复维护。接入后,成员用平台账号登录外部应用,应用从平台获取成员身份与应用成员组,成员被移出群后在 token 刷新时自动失去访问。
概念#
| 概念 | 定义 | 对应实现 |
|---|---|---|
| 应用 | 接入方。一个应用绑定一个群 | OAuth Client |
| 群 | 平台上的小组,授权围绕其发生。应用绑定的群 | Forum(is_group=true) |
| 群成员 | 已加入该群且状态正常的用户 | forum_memberships(status=active) |
| 应用成员组 | 群内的权限分组,决定用户能看到什么内容,如"高级会员" | ForumPermissionGroup(成员组) |
| 授权 | 用户同意向某个应用共享哪些信息 | oauth_grants |
| 回调地址 | 授权完成后平台将用户送回应用的地址,必须与注册值完全一致 | OAuthClient.redirect_uris |
应用成员组与群角色是两个独立维度:群角色(创建者 / 管理员 / 成员)管"谁能管理这个群",应用成员组管"用户能看到什么",互不影响。
授权流程概览#
完整的用户登录流程是 OAuth 2.0 授权码流程 + PKCE,符合 OIDC 规范。一次授权的步骤:
- 用户在外部应用点击"用平台账号登录",应用将浏览器跳转到平台的授权端点;
- 若用户未登录平台,先登录,随后平台展示同意页,列出应用名将获取的信息;
- 用户同意后,平台将一次性授权码送回应用的回调地址;
- 应用后端用授权码换取 access token(以及 refresh token、id_token);
- 应用调用 userinfo 端点获取用户的身份、群成员身份与应用成员组;
- 应用依据应用成员组决定向用户展示的内容。
协议细节、参数定义与示例见授权码流程。平台的课程、帖子等业务数据不参与该流程:本平台是纯身份提供方,应用只能获得授权范围内的身份与群组信息。
非群成员#
若用户已登录平台但不是该应用绑定群的成员,授权流程 不会被拒绝。平台照常完成授权,但在 userinfo 中明确标记:
{ "group": { "is_member": false }, "member_groups": [] }
后续展示什么内容(访客视图、引导加入群、完全锁定)由应用自行决定。
设计原则#
- 最小权限:平台按"申请 ∩ 获批"签发 scope,未获批的 scope 不会出现在 token 与 userinfo 中。
- 短效 token:access token 有效期 1 小时;刷新时平台重新校验用户群成员关系,被移出群的用户最迟在下一次刷新时失去访问。
- 回调地址精确匹配:授权时提交的
redirect_uri必须与注册值逐字符一致,杜绝开放重定向。 - 一切可撤销:用户可撤销对某应用的授权,撤销后该应用名下其全部 token 即时吊销;平台管理员可禁用应用,禁用即吊销该应用全部 token。
