Canvas CLI 的 SSO 接入
Portal 如何兑换用户画布凭证、传给 CLI,并完成刷新和注销
1. 整个流程是什么
用户登录 Portal → Portal 服务端用用户 SSO token 换取 EasyAI 画布 token → Portal 把画布 token 传给 CLI → CLI 操作该用户有权限的画布。
本文中的 Portal 指客户自己的门户系统。客户只需要已经部署的 EasyAI 接口地址、Portal 用户的有效 SSO token 和可安装的 Canvas CLI,不需要 EasyAI 后端源码。
CLI 安装并运行在 Portal 服务端或它调用的智能体运行环境中。用户通过网页使用 Portal 时,也是由 Portal 后端启动 CLI,浏览器不直接执行命令。
| 名称 | 谁签发 | 谁使用 | 用途 |
|---|---|---|---|
| Portal SSO token | Portal 身份服务 | Portal 服务端提交给 EasyAI | 证明当前用户是谁 |
画布 accessToken | EasyAI | CLI | 携带在画布 API 请求中,执行授权范围内的操作 |
画布 refreshToken | EasyAI | Portal 服务端 | 更新画布访问凭证,不交给 CLI |
兑换请求和响应中都有 accessToken 字段,但代表不同系统的 token。下文用 ssoToken 和 canvasSession.accessToken 区分它们。
2. 接入前需要什么
| 接入方 | 准备内容 |
|---|---|
| Portal | 提供用户身份验证接口;让服务端能获取当前用户的有效 SSO token |
| EasyAI 部署方 | 配置 SSO_API_URL 指向 Portal 身份接口,并向 Portal 提供 EasyAI API 根地址 |
| Portal 智能体运行环境 | 安装 Canvas CLI,能够通过网络访问 EasyAI API |
Canvas CLI 认证能力默认开启,不需要额外的功能开关。用户禁用、组织登录限制、设备禁用和项目权限仍然有效。
EasyAI 部署方配置:
这是校验 token 并返回用户信息的后端接口地址,不是 Portal 登录页面,也不是 CLI 的 API 地址。CLI 使用的是 EasyAI API 根地址,例如 https://51easyai.com/api。
EasyAI 按现有 SSO 协议请求 Portal:
Portal 成功时返回 HTTP 200 和 JSON 对象:
id 和 username 必须是非空字符串;id 应是稳定的用户标识。tenantId 可省略或为 null,传入时必须是字符串。organizationIds 对应已有的 EasyAI 组织 ID。用户资料、组织及角色同步规则沿用SSO 单点登录对接。
Portal 应对无效、过期 token 返回 HTTP 401 或 403。EasyAI 的验证请求超时为 10 秒,不自动重试、不跟随重定向。
3. Portal 向 EasyAI 兑换凭证
请求
POST {EASYAI_API_BASE_URL}/auth/client/sso
该接口直接校验传入的 SSO token,无需先进行 EasyAI 网页登录,也不需要额外授权码。
| 字段 | 必填 | 说明 |
|---|---|---|
accessToken | 是 | Portal 用户 SSO token,最多 16384 字符 |
deviceId | 否 | 调用设备标识,最多 128 字符;省略时生成 UUID 并返回 |
agentName | 否 | 智能体名称,最多 80 字符;默认 EasyAI Canvas Agent |
agentInstance | 否 | 智能体实例标识,最多 128 字符;默认使用 deviceId |
clientVersion | 否 | 调用方版本,最多 256 字符 |
os | 否 | 运行系统,最多 256 字符 |
已传字段必须是非空字符串。不要传 userId、tenantId、scopes、clientId 或 SSO_API_URL 等额外字段;这些字段会被拒绝。用户身份和权限以可信 SSO 返回的信息及 EasyAI 授权规则为准。
响应
成功返回 HTTP 200,响应正文就是会话对象,没有 status/data 包装。以下 token 和日期仅用于说明字段:
Portal 应按用户保存整个响应对象。accessToken 用来调用画布;refreshToken、sessionId、deviceId、clientId 用于刷新和注销;有效期字段用于决定何时刷新。
每次兑换创建新会话。相同 deviceId 不代表幂等请求,也不自动替换旧会话。正常运行应复用、刷新已有会话,不要在每条 CLI 命令前重新兑换。
4. 认证信息具体怎么交给 CLI
Portal 在启动 CLI 子进程时,通过环境变量传入 EasyAI 返回的画布 accessToken。CLI 会读取这个值,并自动添加 HTTP 请求头。
| CLI 环境变量 | 填什么 |
|---|---|
EASYAI_CANVAS_BASE_URL | EasyAI API 根地址,例如 https://51easyai.com/api |
EASYAI_CANVAS_ACCESS_TOKEN | 兑换或刷新响应中的 accessToken,不是 Portal SSO token |
对应关系就是:
从命令的角度看,相当于:
Portal 服务端应为每个子进程单独传 env,不要修改全局环境变量供多个用户共用。完整示例见下一节,它也会隔离已有 CLI 登录配置。
Portal 只把有效的画布访问凭证交给 CLI。刷新凭证留在 Portal 服务端;用户 SSO token 用于兑换,不直接用于 CLI 画布请求。此接入方式不需要执行 easyai-canvas auth login。
5. 不依赖 EasyAI 源码的完整示例
在 Portal 服务端安装公开发布的 CLI:
下面是可独立保存为 portal-canvas.mjs 的 Node.js 示例,使用 Node.js 22 内置能力,不依赖任何 EasyAI 后端文件。它演示“兑换 → 传凭证给 CLI → 查询项目 → 注销”。
提供实际部署地址和当前用户的有效 Portal SSO token,然后运行:
成功时输出该用户的项目列表;新用户没有项目时,列表为空也属于成功。真实服务应从当前用户的服务端会话读取 SSO token,而不是把真实 token 固定写入代码、命令历史或智能体提示词。
多次操作时,在 Portal 的受保护会话存储中保存 canvasSession,每次运行 CLI 都传入该用户当前有效的 accessToken。任务结束或用户退出时,再根据业务需要注销,不必像一次性示例那样每执行一条命令就注销。
6. 凭证过期后怎么继续使用
画布访问凭证有效期为 10 分钟;刷新凭证有效期为 7 天,每次成功刷新都会轮换,并按现有规则重新计算有效期。
Portal 应在运行 CLI 前检查 accessTokenExpiresAt,例如剩余不足 60 秒时先刷新,再启动 CLI。
刷新调用 POST {EASYAI_API_BASE_URL}/auth/client/refresh:
保存刷新响应中的新 accessToken、refreshToken 和有效期,并保留原 deviceId。现有刷新响应不额外返回 deviceId。
同一会话的刷新必须串行,包括多个 Portal worker 之间的调用。旧刷新凭证被重复使用会触发防重放逻辑并撤销会话。不要把同一个刷新凭证复制给多个并发任务自行刷新。
已有 CLI 进程的环境变量不会随 Portal 存储更新而自动变化。因此此方案适合“Portal 按命令启动 CLI”:刷新后启动的下一个进程使用新 token;长期驻留的 CLI 进程需要另行管理续期或重启。
7. 任务结束或用户退出时怎么处理
Portal 调用 POST {EASYAI_API_BASE_URL}/auth/client/logout,请求体与刷新时使用的四个字段相同。成功后清除 Portal 保存的该会话;旧 token 将无法继续操作画布,刷新也会被拒绝。
刷新和注销接口均按 HTTP 2xx 判断成功,沿用现有接口的状态码和响应格式。
Portal 退出登录不会自动立即撤销 EasyAI CLI 会话。 若需要同步退出,由 Portal 主动调用 logout。刷新时不会再次调用 Portal SSO,因此 SSO token 过期也不等于已有画布会话立即失效;重新兑换则必须提供有效 SSO token。
8. 接口错误与接入边界
| 兑换接口 HTTP 状态 | 含义 |
|---|---|
| 400 | 缺少 token、字段类型错误或存在未知字段 |
| 401 | Portal SSO token 无效或过期 |
| 403 | 用户禁用、组织禁止登录或设备禁用 |
| 502 | Portal 身份服务返回非法 JSON 或不符合约定的用户信息 |
| 503 | SSO 地址未配置、连接失败、超时或上游服务故障 |
错误体沿用 EasyAI 现有格式,以 HTTP 状态为主要判断依据,不透传 Portal 身份服务的原始错误内容。
- 有 token 不代表有所有画布权限。 CLI 仍只能操作该用户有权限的项目。
- CLI token 不是普通网页登录凭证。
project open可以打开页面,但不会自动登录浏览器。 - 写操作失败不要直接重放。 网络中断时先确认画布当前状态,避免重复创建内容。
- 每个用户独立保存和传递凭证。 不用共享管理员 token 代替所有 Portal 用户。