Web 接入与运行态调用
使用百积木标准浏览器 SDK 完成平台应用启动、PKCE、会话和 Runtime 方法调用。
环境托管应用必须使用公共 npm 包 @baijimu/platform-application-sdk 接入平台。不要在项目中复制
sdk.js,也不要由每个平台应用分别实现授权跳转、PKCE、token 存储、CModel 解析和 Runtime URL
拼接。
安装标准 SDK
pnpm add --save-exact @baijimu/platform-application-sdk@7.0.0提交项目锁文件,保证构建和回滚使用已解析的精确依赖版本。SDK 是应用的构建时依赖,不会在目标环境 部署新服务,也不会改变 Bundle 安装内容。
通过 PLATFORM_APPLICATION 项目类型新建的项目应已经包含 SDK、bootstrap() 入口、部署配置文件和
平台应用声明。若项目中仍存在自实现的 PKCE、token 缓存或 Gateway client,不能只在旁边新增 SDK;应删除
重复实现,让授权生命周期和逐方法调用统一经过 SDK。
读取同源环境配置
环境托管应用使用 SDK 的专用初始化入口:
import { createPlatformApplicationClientFromHostedConfiguration } from "@baijimu/platform-application-sdk";
const client = await createPlatformApplicationClientFromHostedConfiguration(applicationDefinition.id);applicationDefinition.id 是当前应用稳定的 platformAppId。SDK 只从当前 HTTPS origin 的
/.well-known/baijimu-platform-application.json 读取配置,并校验应用身份和精确 origin。
该文件由平台在 Bundle 安装或升级时的托管流程自动提供,开发者无需创建静态站点或手工部署配置文件,也不能让应用构建归档覆盖它。
历史 STATIC_SPA 站点需要完成 环境托管迁移,只升级 npm 依赖不会生成同源配置。
新应用在独立 origin 的根路径运行,配置不含 releasePath。已有 SDK 6 部署继续使用原配置;历史 SDK 6 归档首次安装到新环境需要升级 SDK、重新构建并发布新应用版本。应用版本与 Bundle 安装、升级和回滚不变。
配置字段如下:
| 字段 | 来源与含义 |
|---|---|
contractVersion | 同源配置合同版本,SDK 7 使用 2.0.0 |
platformAppId | 当前平台应用的稳定身份 |
applicationOrigin | 该应用在当前环境的 HTTPS origin |
appGatewayApiBase | 当前环境的 App Gateway API 地址 |
authorizationUrl | 当前环境的网页授权地址 |
managementUrl | 可选的当前环境管理入口 |
SDK 拒绝配置重定向、缺失字段、未知字段和身份不匹配,不缓存配置,也不从 URL 参数或公共 SaaS 地址回退。
配置不包含 installId、工作区、用户、token 或密钥;真实安装选择器由启动 URL 提供,服务端负责权限校验。
只升级 SDK 不会让外部站点取得平台授权,应用还必须按环境托管方式创建新版本并升级 Bundle。
旧项目应删除 window.__APP_CONFIG__ 手工地址注入、签名启动初始化和自实现授权逻辑。
createPlatformApplicationClient(config) 仅用于显式受控集成或本机测试,不能用它绕过平台托管要求;
外部自托管应用使用自己的后台授权。
在业务页面之前启动
const session = await client.bootstrap();bootstrap() 统一执行以下状态机:
读取 installId
-> 有 code:校验 state 并兑换本次授权 token
-> 当前 client 已有未过期内存会话:进入应用
-> 都没有:创建 PKCE 请求并跳转网页授权页SDK 会校验返回 token 的 workspaceId、runtimeAppId、installId、platformAppId 和过期时间,
token 只保存在当前 client 实例的内存中。每个页面使用一个 client,同一实例的重复或并发
bootstrap() 不重复发起授权。新开页面或刷新必须重新经过平台授权页,以当前平台登录身份兑换
新 token,不能恢复上次打开时的应用身份。SDK 会删除当前应用和安装的旧 localStorage token。
不要把 token 写入 localStorage、sessionStorage、Cookie 或 URL,也不要通过自有缓存跳过 SDK 初始化。
PKCE verifier 和预期 state 仍需在 sessionStorage 中跨授权跳转保存;它们不是应用登录 token。
授权成功后删除 PKCE 临时数据,并从地址栏移除授权参数。
它只移除一次性的 code 和 state,会保留平台入口要求的 installId。业务代码不要再次清空整个查询串。
迁移 SDK 6
SDK 6.0.0 取消持久化应用会话。更新依赖和锁文件后,必须重新构建并发布平台应用、更新 Bundle 引用, 已打开的旧页面需要重新加载。发布 npm 包本身不会改变已部署的 JavaScript。
旧应用除了更新依赖,还需删除自实现的 token 缓存。SDK 2.x/3.x 的初始化应迁移到同源托管配置入口;
SDK 4.x 的调用需检查 /invoke 及结构化 target 的兼容性。目标网关须支持 SDK 5 起采用的领域调用协议。
新开或刷新会重新核验平台当前身份。已打开应用不会因另一个域名的平台账号切换自动收到通知;
即时退出和账号切换联动需要平台的可信会话失效机制,不得信任 URL 或任意跨域消息中传来的 userId。
clearSession() 只清客户端状态,服务端撤销使用 revoke()。
验收至少覆盖:浏览器已有账号 A 的旧应用缓存、平台切换为账号 B、重新打开/刷新应用后接口身份为 B; 同时验证 PKCE 回跳、并发初始化、token 过期和授权途中退出。SDK 不自动重放失败的业务请求。
调用模块方法
业务组件只传平台应用版本已声明的结构化 target、method 和方法参数:
const projects = await client.call(
{
type: "module",
bundleId: "project-directory",
moduleId: "project-directory",
},
"listProjects",
{ offset: 0, limit: 50 },
);SDK 使用规范调用路由,并生成包含 target、method 和 params 的请求体:
POST {appGatewayApiBase}/workspace-runtime/apps/{installId}/invoke新应用不得提交 Runtime service;/services/{service}/methods/{method} 只服务历史 SDK 2.x 应用。
App Gateway 会校验 token、安装、默认 Runtime 绑定、平台应用版本的
方法声明和工作区权限;前端不选择后端实例、不读取具体 businessId,也不持有模块服务凭证。完整协议见
调用模块方法。
错误与会话处理
import {
CModelFailureError,
PlatformApplicationSdkError,
} from "@baijimu/platform-application-sdk";
try {
await client.call(
{ type: "module", bundleId: "project-directory", moduleId: "project-directory" },
"listProjects",
{},
);
} catch (error) {
// 由 SDK 判定会话失效;不要仅凭业务 errorCode 或 HTTP 状态重登。
if (!client.getSession()) {
client.restartAuthorization();
throw error;
}
if (error instanceof CModelFailureError) {
console.error(error.errorCode);
} else if (error instanceof PlatformApplicationSdkError) {
console.error(error.code);
}
}SDK 6.0.0 在 App Gateway 返回 APP_GATEWAY_UNAUTHORIZED 时清除当前安装会话,也会处理网关返回的非结构化 HTTP 401。
后端业务返回合法 CModel UNAUTHORIZED 时,即使 HTTP 状态是 401,SDK 仍保留会话;应用应展示业务错误,不能重新授权。
参数错误、能力未声明、目标服务异常和网络失败同样不能触发登录循环。以 client.getSession() 是否已由 SDK 清空作为重新授权的依据,
不要维护另一份会话状态,也不要在捕获到业务 UNAUTHORIZED 时自行清理 SDK 会话或自动重放业务请求。
需要主动注销时调用 await client.revoke();需要重新授权时调用 client.restartAuthorization()。
平台应用没有另一套 PLATFORM_APPLICATION token,也不通过通用 HTTP 代理访问平台内部 API。需要新增
能力时,应先把能力定义为 Runtime 模块方法并发布不可变模块版本,再把该方法加入平台应用版本的
methodDefinitions。
分享与管理入口
面向其他用户分享通用功能时,使用 Manager 的 /bundle-app/{bundleId}/{platformAppId} 路由。
分享当前工作区的具体页面时,使用 /workspace/{workspaceId}/bundle-app/{bundleId}/{platformAppId},
并通过 URL 编码后的 target 参数携带原生应用内地址,例如 /orders/123?tab=items 或
/#/orders/123?tab=items。这是普通 href,可以本地拼接,无需链接生成请求,详见
用普通 href 打开应用内页面。
不要分享包含当前工作区 installId 的应用启动地址。应用配置了 managementUrl 后,可以使用
client.openManagementRoute(route) 打开管理页面;未配置时 SDK 会明确失败,不会猜测 Manager 地址。
会话失效
以下情况应终止当前应用会话并重新授权:
- token 已到期或被撤销。
- Bundle 安装已经停用、卸载或升级后使旧 token 失效。
- 返回的 token 与当前
workspaceId、runtimeAppId、installId不一致。 - App Gateway 明确拒绝当前会话,SDK 已将其清空。
不要在所有业务错误上盲目跳转授权页。参数错误、目标服务异常和能力未声明应分别展示真实错误,避免形成授权循环。
本地开发
本地回跳地址必须与实际托管入口同源。若入口是已部署域名,本地 localhost 回跳不会通过同源校验。托管初始化要求真实 HTTPS 同源配置;本地页面展示可使用明确的测试配置,但完整授权联调应发布到目标测试环境并从该环境的安装入口启动,不能用外部 URL 替代环境托管。验证时保证:
- 页面可以从入口参数取得真实
installId。 - HTTPS、端口和域名与登记入口一致。
- Hash Router 和普通查询参数都能正确读取回跳字段。
- 浏览器刷新后不会丢失 PKCE 会话。
- 本地配置明确指向本次开发环境,不回退到公共 SaaS。