百积木文档
开发指南平台应用、模块与 Bundle 开发平台应用开发

App Gateway 接入与配置

为复用百积木用户与工作区体系的平台应用选择 App Gateway,并完成入口、授权、能力、调用和发布配置。

App Gateway 是平台应用复用百积木登录用户、工作区安装态和权限体系的标准业务入口。 只要应用由 Bundle 安装到工作区,并且页面代表当前平台用户调用该安装可用的能力,就应 使用 App Gateway。

团队开发前端并从百积木工作区打开、复用平台身份时,应创建独立的 Platform Application, 使用 ENVIRONMENT_HOSTED_APP 由目标环境托管,通过同源配置、网页授权和 PKCE 获取 appClientToken。 历史 TRUSTED_EXTERNAL_APP 的启动和平台授权已被拒绝;外部自托管站点应使用自己的后台授权。

选择平台应用入口

entryType适用场景App Gateway 接入方式
PLATFORM_ROUTE平台管理端已经内置的页面继承平台管理端当前登录态,不执行外部应用 PKCE
ENVIRONMENT_HOSTED_APP由当前环境托管、复用平台用户和工作区的前端读取同源配置,通过网页授权 + PKCE 获取 appClientToken
TRUSTED_EXTERNAL_APP(历史类型)待迁移的外部前端当前启动和授权链路拒绝,须重新发布为环境托管应用
EXTERNAL_URL不访问平台能力的普通链接不接入 App Gateway

App Gateway 应用凭证

环境托管平台应用调用 App Gateway 时使用 appClientToken。该 token 由网页 授权码兑换流程签发,并绑定当前用户、工作区、默认 Runtime 应用、平台应用安装和 授权范围。

调用链

百积木平台用户
  -> 从工作区打开平台应用 accessUrl
  -> 网页授权页校验登录态、工作区访问权和安装记录
  -> PKCE 授权码兑换 appClientToken
  -> 浏览器请求公开前缀 /app-gateway/api
  -> App Gateway 校验结构化 target、方法、用户、安装和版本
  -> 按安装记录把模块领域引用 或 interface 解析为 Runtime businessId
  -> 校验工作区方法权限并调用绑定的模块方法
  -> 返回统一响应

应用前端只依赖公开、稳定的 App Gateway 契约。公共 SaaS 当前前缀是 https://api.baijimu.com/app-gateway/api,但它不是所有部署的默认值;实际前缀必须由当前环境的 部署配置注入。不要在业务代码中硬编码平台内部服务、网关地址、单个工作负载 IP 或端口。

App Gateway 负责完整的应用调用边界:

  • 确认“谁在调用、属于哪个安装、当前版本允许调用什么 target 和方法”。
  • 固定 module target 按安装账解析;interface target 按当前安装的 interfaceBindings 解析成具体 Runtime businessId
  • 使用平台维护的安装态调用身份向目标 Runtime 网关发起调用,并传递已验证的当前用户上下文。

前端不得读取、缓存或提交具体 businessId,也不自行拼接内部调用信封。 随 Bundle 安装的平台应用必须在 methodDefinitions 声明 module | interface target 和精确方法; 安装器负责校验目标 Module 只能由当前 Bundle 或其依赖 Bundle 提供,并生成运行态绑定。

配置一:创建独立平台应用

每个可独立发布的平台应用都应有稳定的 platformAppId 和独立的平台项目。不要把前端 页面仅作为 Bundle 中一个匿名 URL;否则平台无法为它管理版本、Bundle 安装边界和能力声明。

由环境托管且复用平台身份的前端在专属 PLATFORM_APPLICATION 项目的 baijimu.platform-application.json 中使用:

{
  "schemaVersion": "3.0.0",
  "entry": {
    "type": "ENVIRONMENT_HOSTED_APP",
    "urlTemplate": "/index.html",
    "openMode": "WORKSPACE_TAB"
  },
  "manifest": {}
}

platformAppId 是项目与 Bundle 资源的一对一绑定身份,不在配置文件中重复声明。

环境托管入口是版本内相对根路径,不能包含外部 URL、查询串、hash 或 {installId}。 平台解析实际部署地址并在启动时追加 installIdworkspaceIduserIdappClientToken、业务密钥 和内部服务地址都不能放进入口 URL。

如果页面本来就是平台管理端源码中的内置路由,才使用:

{
  "schemaVersion": "3.0.0",
  "entry": {
    "type": "PLATFORM_ROUTE",
    "urlTemplate": "/workspace/example",
    "openMode": "CURRENT"
  },
  "manifest": {}
}

使用 PLATFORM_ROUTE 前必须确认这个精确相对路径已经由平台管理端源码注册并随平台版本上线。 /workspace/{workspaceId}/platform-app/{platformAppId} 是通用平台应用宿主地址,不会自动加载项目里的 React 构建产物,不能作为独立 Bundle 应用的默认路由。

完整的入口选择规则见 入口类型与应用清单

配置二:声明最小能力

平台应用项目配置必须在 methodDefinitions 中声明 target 和模块方法。固定依赖直接声明 module:

[
  {
    "target": {
      "type": "module",
      "bundleId": "wechat-connector",
      "moduleId": "wechat-official-account"
    },
    "methods": [
      "authorizationUrl",
      "listAuthorizedAccounts",
      "createDraft"
    ]
  }
]

如果产品要求允许不同 Module 替换实现,才把 target 改为 interface:

{
  "methodDefinitions": [
    {
      "target": {
        "type": "interface",
        "name": "wechat-official-account"
      },
      "methods": [
        "authorizationUrl",
        "listAuthorizedAccounts",
        "createDraft"
      ]
    }
  ],
  "manifest": {
    "interfaceBindings": {
      "wechat-official-account": {
        "bundleId": "wechat-connector",
        "moduleId": "wechat-official-account"
      }
    }
  }
}

安装器根据模块领域引用 解析当前 Runtime 的具体 service。前端发送与版本声明一致的结构化 target; 解析结果和调用身份只存在于安装态,不能由前端选择、改写或持久化。

不要声明通配权限,也不要把未来可能使用的管理方法提前加入当前版本。平台应用不能用 methodDefinitions 代替平台内部 HTTP API 授权;它只能声明已安装 Runtime 模块的方法。

能力声明、已启用的精确 Bundle 安装和当前用户的工作区/方法权限同时生效;其中任何一层不满足,App Gateway 都应拒绝 调用。字段规则见 声明应用能力

配置三:使用网页授权 + PKCE 取得应用身份

ENVIRONMENT_HOSTED_APP 使用 @baijimu/platform-application-sdk 从 URL 读取 installId,生成 PKCE 会话并跳转当前部署配置提供的统一授权页。公共 SaaS 的授权页地址只是一个部署示例:

https://console.baijimu.com/#/platform-app-authorize
  ?installId=pia_xxx
  &redirectUri=https%3A%2F%2Fapp.example.com%2F
  &codeChallenge=...
  &codeChallengeMethod=S256
  &state=...

平台网页授权页校验登录用户、工作区权限、精确 Bundle 应用安装和版本能力范围,然后只向同源 redirectUri 回传一次性 code。SDK 校验 state 后执行以下兑换:

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"
}

返回的 appClientToken 同时绑定用户、工作区、默认 Runtime 应用、平台应用安装和 授权范围,不能跨 Runtime 或跨安装复用。完整流程见 平台应用授权与 PKCE

配置四:统一公开 API 前缀

安装标准 SDK:

pnpm add --save-exact @baijimu/platform-application-sdk@7.0.0

应用启动层从同源环境配置创建唯一客户端,缺少配置时直接失败:

import { createPlatformApplicationClientFromHostedConfiguration } from "@baijimu/platform-application-sdk";

const client = await createPlatformApplicationClientFromHostedConfiguration(applicationDefinition.id);

await client.bootstrap();

SDK 从 /.well-known/baijimu-platform-application.json 读取当前应用 origin、 App Gateway 与授权地址。该配置由平台托管流程提供,不能被前端归档覆盖,也不接受来自查询参数的替代地址。

SDK 使用的标准入口如下:

用途请求
授权码兑换POST /workspace-runtime/apps/{installId}/token/exchange
撤销 tokenPOST /workspace-runtime/apps/{installId}/token/revoke
调用模块方法POST /workspace-runtime/apps/{installId}/invoke

除 token exchange 外,调用都携带:

Authorization: Bearer {appClientToken}

业务组件通过客户端调用方法,第三个参数直接作为方法请求体:

const result = await client.call(
  {
    type: "module",
    bundleId: "wechat-connector",
    moduleId: "wechat-official-account",
  },
  "listAuthorizedAccounts",
  { offset: 0, limit: 50 },
);

完整请求和响应协议见 调用模块方法, 启动状态机见 Web 接入与运行态调用

发布与安装

环境托管前端从专属项目主线按精确版本构建,项目根目录 package.json 版本必须一致。 CLI 等待构建完成后创建不可变平台应用版本,再由 Bundle 引用精确版本;完整命令见 创建版本并纳入 Bundle

使用 bundle manifest include <bundle> platform-application 选择目录中的应用与精确版本,CLI 自动写入 definition.platformApplications。安装或升级后,平台自动提供托管入口和同源配置,无需开发者另行创建或部署静态站点。

修改前端源码、入口或方法声明后,都需要发布新的项目与平台应用版本,由新的 Bundle 版本引用并升级目标工作区。 已发布版本不能改绑提交或替换构建产物;只创建平台应用版本不会自动升级已经安装的 Bundle 资源。

安装或升级预览会汇总平台应用需要调用的、由其他依赖 Bundle 提供的精确方法。只要清单 非空,Manager 和 CLI 都要求安装用户确认,并把同一份结构化清单回传;后端会重新解析并 逐项比对,不能通过修改请求扩大范围。同一 Bundle 内的方法不会重复提示,但仍受相同的 运行态调用身份、版本声明和当前用户权限约束。

验收清单

  1. 平台应用有稳定 platformAppId 和独立项目。
  2. 前端使用 ENVIRONMENT_HOSTED_APP 和版本内入口,启动地址由平台追加 installId,同源配置校验通过。
  3. 网页授权回跳只携带一次性授权码,不在 URL 中传 token。
  4. token exchange 返回的工作区、runtimeAppId 和安装信息与当前入口一致。
  5. 前端只通过公开 /app-gateway/api 前缀访问平台能力。
  6. 前端通过标准 SDK 调用平台应用版本声明的 module | interface target 和 method
  7. Bundle 的资源依赖或接口绑定与安装态运行服务一致,且平台应用版本已精确声明对应方法。
  8. 已声明的方法可调用,未声明的方法被拒绝。
  9. 不同用户、工作区和安装之间不会复用 token。
  10. appClientToken 不出现在入口 URL、日志、埋点或错误上报中。
  11. 业务系统密钥不进入平台应用前端。
  12. 新平台应用版本已被 Bundle 精确引用,并已升级到目标工作区。
  13. 跨 Bundle 方法清单已经由安装用户确认,未确认或被篡改的请求会被拒绝。

排障时先判断失败发生在入口、网页授权、token exchange、App Gateway 权限校验、 运行态解析还是目标模块执行。不要因为某一层配置错误就绕开 App Gateway 的安装和授权 校验;应在实际失败层修复配置或实现。

本页内容