应用门户(「我的应用」)
给普通用户提供的一个轻量入口:登录后看到自己有权访问的应用,点「打开」即跳过去, 靠 OIDC SSO 免密登录。填补了普通用户(无管理权限)登录后无功能可用的空洞。
1. 端点
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/user/apps | 我的应用列表(按 visibility 三级过滤 + portal_visible) |
| GET | /api/user/permissions | 我的权限视图(角色 + 功能分组,profile「我的权限」卡数据源) |
无需管理权限,任何登录用户可调。返回结构:
{
"success": true,
"data": [
{
"client_id": "app_xxx",
"client_name": "ExoMind",
"launch_url": "https://exomind.example.com",
"authorize_url": "/authorize?client_id=app_xxx&redirect_uri=...&response_type=code&scope=openid+profile+email&state=...",
"description": "个人知识库:把散落的资料变成可检索的知识",
"capabilities": ["检索沉淀的知识", "写作与整理知识"],
"portal_visible": true,
"visibility": "system"
}
]
}
用户视角文案(description / capabilities)
门户卡片对用户回答两个问题——“这是什么“和“你能干什么”:
description:应用描述(一句话卖点),在「OAuth 客户端」编辑表单维护,所有用户相同。capabilities:当前用户在该应用里能做的动作(按人渲染——只读用户与管理员看到不同的能力行,不说谎)。数据链路:- 菜单管理里把目录(M)的「所属应用」挂到某个 client(
menus.client_id,整棵子树归属该应用); - F 按钮的「业务描述」(
menus.action_label)即用户文案,如「检索沉淀的知识」;留空回退菜单名称; - 本端点取「用户绑定的权限 ∩ 该应用子树」的文案列表,按菜单 sort_order 保序。
- 菜单管理里把目录(M)的「所属应用」挂到某个 client(
菜单名(menu_name)保持无歧义的管理锚点(如「读取权限」),角色树/菜单管理用;action_label 面向终端用户。权限标识(read/write)不进用户界面。
/api/user/permissions 返回 { roles, groups }:角色徽章(role_name/role_type)+
按功能菜单分组的操作(action_label 优先回退 menu_name,原始权限标识在
action.permission 供前端 hover 排障)。平台 admin 全量分组,普通用户按角色绑定过滤。
2. 应用可见性
门户只展示同时满足两个条件的 client:
- visibility 允许当前用户看到(
system全员 /org同组织 /user仅 owner) portal_visible=true(管理端 / OAuth client 列表可切换)
visibility 决定“能不能看到“,portal_visible 决定“要不要在门户露面“。两者正交。详见 全平台客户端。
3. 「打开」怎么免密跳转(SSO 握手)
每个应用返回两个 URL:
launch_url:应用主页(从client_uri或redirect_uri的 origin 推导)——直接跳,靠浏览器已有的 SSO cookie 免密authorize_url:走 OIDC/authorizecode 流程——若 SSO cookie 失效会触发登录,登录后回应用 callback
前端默认走 launch_url(应用首页 + SSO cookie 免密,最快);cookie 失效时落到 authorize_url 完成 OIDC 握手后跳回。
为什么需要 SSO cookie
首次登录 AuthKeystone 会在浏览器种 HttpOnly 的 auth_session SSO cookie(默认 24h)。门户“打开“应用时,浏览器带着这个 cookie 访问应用 / /authorize,AuthKeystone 认定已登录 → 免密发 code 或直接放行。cookie 过期才需重新登录。
这与下游接入的 SSO 会话是同一套 cookie。业务若选择本地登出,用户再次进入时可在 24h 内无感登录;需要退出整个身份会话时,使用全局登出。详见 下游接入指南 3.4 节。