App Gateway 接入与配置
为复用百积木用户与工作区体系的平台应用选择 App Gateway,并完成入口、授权、能力、调用和发布配置。
App Gateway 是平台应用复用百积木登录用户、工作区安装态和权限体系的标准业务入口。 只要应用由 Bundle 安装到工作区,并且页面代表当前平台用户调用该安装可用的能力,就应 使用 App Gateway。
最常见的场景是:团队开发一个独立部署的前端应用,但用户仍从百积木工作区打开它。
此时应创建独立的 Platform Application,使用 TRUSTED_EXTERNAL_APP 入口,通过
网页授权和 PKCE 获取 appClientToken,再从公开平台 API 前缀调用 App Gateway。
选择平台应用入口
entryType | 适用场景 | App Gateway 接入方式 |
|---|---|---|
PLATFORM_ROUTE | 平台管理端已经内置的页面 | 继承平台管理端当前登录态,不执行外部应用 PKCE |
TRUSTED_EXTERNAL_APP | 独立部署、复用平台用户和工作区的 Web 应用 | 通过网页授权 + PKCE 获取 appClientToken |
EXTERNAL_URL | 不访问平台能力的普通链接 | 不接入 App Gateway |
App Gateway 应用凭证
可信外部平台应用调用 App Gateway 时使用 appClientToken。该 token 由网页
授权码兑换流程签发,并绑定当前用户、工作区、默认 Runtime 应用、平台应用安装和
授权范围。
调用链
百积木平台用户
-> 从工作区打开平台应用 accessUrl
-> 网页授权页校验登录态、工作区访问权和安装记录
-> PKCE 授权码兑换 appClientToken
-> 浏览器请求公开前缀 /app-gateway/api
-> App Gateway 校验逻辑接口、方法、用户、安装和版本
-> 按安装记录 interfaceBindings 解析具体 Runtime businessId
-> 校验工作区方法权限并调用 backend-instance
-> 返回统一响应应用前端只依赖公开、稳定的 https://api.baijimu.com/app-gateway/api 契约。不要在
业务代码中硬编码 gateway2、backend-instance、内部网关地址、单台服务 IP 或端口。
这些属于平台内部路由和运行态实现,不是应用协议。平台应用方法调用不经过主站
/lowcode3/api,也不由前端直接访问 gateway2。
App Gateway 负责完整的应用调用边界:
- 确认“谁在调用、属于哪个安装、当前版本允许调用什么逻辑接口和方法”。
- 调用平台应用安装服务,把逻辑接口按当前安装的
interfaceBindings解析成具体 RuntimebusinessId。 - 使用解析后的具体服务完成工作区方法权限校验和 backend-instance 运行态调用。
前端不得读取、缓存或提交具体 businessId,也不自行拼接内部调用信封。
配置一:创建独立平台应用
每个可独立发布的平台应用都应有稳定的 platformAppId 和独立的平台项目。不要把前端
页面仅作为 Bundle 中一个匿名 URL;否则平台无法为它管理版本、安装、能力和用户授权。
独立部署且复用平台身份的前端使用:
{
"platformAppId": "example-platform-app",
"entryType": "TRUSTED_EXTERNAL_APP",
"entryUrlTemplate": "https://app.example.com/?installId={installId}",
"openMode": "WORKSPACE_TAB"
}入口模板只携带 {installId}。workspaceId、userId、appClientToken、业务密钥
和内部服务地址都不能放进入口 URL。
如果页面本来就是平台管理端源码中的内置路由,才使用:
{
"entryType": "PLATFORM_ROUTE",
"entryUrlTemplate": "/workspace/example"
}完整的入口选择规则见 入口类型与应用清单。
配置二:声明最小能力
平台应用版本必须声明实际使用的逻辑接口和模块方法。新平台应用统一使用 interface,
由安装时的 interfaceBindings 选择具体模块实现:
[
{
"interface": "wechat-official-account",
"methods": ["authorizationUrl", "listAuthorizedAccounts", "createDraft"]
}
]安装记录保存平台生成的绑定,不进入前端配置:
{
"interfaceBindings": {
"wechat-official-account": "m-baijimu-2157"
}
}service 形式仅用于仍然锁定具体 Runtime businessId 的存量版本,不应作为新平台应用
的调用合同,更不能让前端读取该值。
不要声明通配权限,也不要把未来可能使用的管理方法提前加入当前版本。平台应用不能用
methodDefinitions 代替平台内部 HTTP API 授权;它只能声明已安装 Runtime 模块的方法。
能力声明、安装绑定和用户授权同时生效;其中任何一层不满足,App Gateway 都应拒绝 调用。字段规则见 声明应用能力。
配置三:使用网页授权 + PKCE 取得应用身份
TRUSTED_EXTERNAL_APP 从 URL 读取 installId 后,跳转统一授权页:
https://console.baijimu.com/#/platform-app-authorize
?installId=pia_xxx
&redirectUri=https%3A%2F%2Fapp.example.com%2F
&codeChallenge=...
&codeChallengeMethod=S256
&state=...平台网页授权页校验登录用户、工作区权限、应用安装和授权范围,然后只向同源
redirectUri 回传一次性 code。页面校验 state 后兑换 token:
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 前缀
前端应由一个接入层集中管理平台地址:
const platformApiBase =
window.__APP_CONFIG__?.platformApiBase ??
"https://api.baijimu.com/app-gateway/api";不同部署环境通过环境配置替换 platformApiBase,业务组件不要散落生产域名。标准入口
如下:
| 用途 | 请求 |
|---|---|
| 授权码兑换 | POST /workspace-runtime/apps/{installId}/token/exchange |
| 调用模块方法 | POST /workspace-runtime/apps/{installId}/services/{service}/methods/{method} |
除 token exchange 外,调用都携带:
Authorization: Bearer {appClientToken}模块方法的 POST 请求体直接使用方法参数,不再包装 service、method 或 params:
export async function callModule({
platformApiBase,
installId,
appClientToken,
logicalService,
method,
params = {},
}) {
const path =
`${platformApiBase}/workspace-runtime/apps/${encodeURIComponent(installId)}` +
`/services/${encodeURIComponent(logicalService)}` +
`/methods/${encodeURIComponent(method)}`;
const response = await fetch(path, {
method: "POST",
headers: {
Authorization: `Bearer ${appClientToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(params),
});
const payload = await response.json();
if (!response.ok || payload.errorCode !== "0") {
throw new Error(payload.value || `模块调用失败:HTTP ${response.status}`);
}
return payload.data;
}完整请求和响应协议见 调用模块方法, 启动状态机见 Web 接入与运行态调用。
发布与安装
平台应用配置以不可变版本发布,再由 Bundle 引用精确版本:
{
"platformApplications": [
{
"platformAppId": "example-platform-app",
"version": "1.2.0"
}
]
}修改入口、方法能力或回跳同源范围后,需要依次发布平台应用新版本、冻结 Bundle 新版本 并升级目标工作区。只修改前端文件、且入口和方法声明不变时,可以从同一平台项目 commit 构建新 Artifact 并热更新原站点,不需要新平台应用版本;只发布平台应用版本则不会自动 升级已经安装的 Bundle 资源。
验收清单
- 平台应用有稳定
platformAppId和独立项目。 - 独立前端使用
TRUSTED_EXTERNAL_APP,入口模板包含{installId}。 - 网页授权回跳只携带一次性授权码,不在 URL 中传 token。
- token exchange 返回的工作区、
runtimeAppId和安装信息与当前入口一致。 - 前端只通过公开
/app-gateway/api前缀访问平台能力。 - 前端在
{service}路径段传平台应用声明的逻辑接口名,不传 RuntimebusinessId。 - App Gateway 能按当前安装的
interfaceBindings解析具体 Runtime 服务。 - 已声明的方法可调用,未声明的方法被拒绝。
- 不同用户、工作区和安装之间不会复用 token。
appClientToken不出现在入口 URL、日志、埋点或错误上报中。- 业务系统密钥不进入平台应用前端。
- 新平台应用版本已被 Bundle 精确引用,并已升级到目标工作区。
排障时先判断失败发生在入口、网页授权、token exchange、App Gateway 权限校验、 运行态解析还是目标模块执行。不要因为某一层配置错误就绕开 App Gateway 的安装和授权 校验;应在实际失败层修复配置或实现。