平台应用授权与 PKCE
Bundle 安装的可信外部平台应用通过统一网页授权、授权码和 PKCE 获取 appClientToken。
TRUSTED_EXTERNAL_APP 必须使用平台提供的统一网页授权页面:
https://console.baijimu.com/#/platform-app-authorize应用不能自己复制网页授权页,也不能直接调用内部授权接口并传入 userId。平台授权页负责确认登录态、工作区访问权、应用安装和用户授权;外部应用只负责发起标准授权请求和处理回跳。
这里的 token 兑换属于 App Gateway 平台应用授权链路。完整接入配置见 App Gateway 接入与配置。
完整流程
工作区打开 accessUrl
-> 应用读取 installId
-> 应用生成 codeVerifier、codeChallenge 和 state
-> 跳转平台网页授权页
-> 用户登录并确认授权范围
-> 授权页回跳 redirectUri,携带一次性 code
-> 应用校验 state
-> 应用使用 code + codeVerifier 兑换 appClientToken
-> 应用携带 Bearer token 调用授权范围内的接口第一步:生成 PKCE 参数
每次授权生成新的高熵 codeVerifier,并使用 SHA-256 计算 Base64 URL 编码的 codeChallenge:
codeChallenge = BASE64URL(SHA256(codeVerifier))
codeChallengeMethod = S256codeVerifier 和 state 应临时保存在当前浏览器会话中。不要把 codeVerifier 放进 URL。
第二步:跳转网页授权页
授权页使用 Hash Router,因此授权参数必须写在 #/platform-app-authorize 后面的查询字符串中:
https://console.baijimu.com/#/platform-app-authorize
?installId=pia_xxx
&redirectUri=https%3A%2F%2Fapp.example.com%2F
&codeChallenge=...
&codeChallengeMethod=S256
&state=...参数含义:
| 参数 | 是否必填 | 说明 |
|---|---|---|
installId | 是 | 当前工作区安装记录 |
redirectUri | 是 | 授权完成后的回跳地址,必须与应用入口同源 |
codeChallenge | 是 | PKCE challenge |
codeChallengeMethod | 是 | 使用 S256 |
state | 是 | 防止请求伪造和回跳串线的随机值 |
第三步:处理回跳
网页授权成功后回跳 redirectUri,并附加:
?code=一次性授权码&installId=pia_xxx&state=原始state回跳携带的是短期、一次性 code,不是最终 token。应用必须先验证 state 与发起授权时保存的值一致,再执行兑换。
第四步:兑换 token
调用公开平台 API:
POST https://api.baijimu.com/app-gateway/api/workspace-runtime/apps/{installId}/token/exchange
Content-Type: application/json
{
"code": "authorization-code",
"codeVerifier": "original-code-verifier"
}兑换成功后应校验:
- 返回的
workspaceId是有效工作区 - 返回的
runtimeAppId与当前安装绑定的默认 Runtime 应用一致 - token 对应的
installId与启动安装一致 - token 尚未过期
appClientToken 没有 PLATFORM_APPLICATION 或 RUNTIME_APP 两套 scope;所有通过
Bundle 安装的平台应用都使用同一 Runtime 绑定 token 契约。
授权码只能使用一次。兑换失败、token 到期或服务返回未授权时,应清理当前安装的本地会话并重新开始授权流程。
不要把 token 放在回跳 URL
URL 会进入浏览器历史、Referer、代理和访问日志。网页授权页只回传一次性授权码,最终 appClientToken 必须通过后端 token exchange 响应取得。