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

安全与故障排查

保护 Bundle 平台应用 token,并按授权链路定位入口、回跳和权限问题。

安全要求

  • 使用 PKCE S256,每次授权生成新的 verifier 和 state。
  • redirectUri 必须与登记的应用入口同源。
  • 不在 URL、日志、错误上报、埋点或截图中记录 token。
  • token 仅保存在 SDK client 内存中,校验 workspaceId + runtimeAppId + installId 和过期时间;不要自行持久化。
  • 内存保存 token 不消除 XSS 风险;必须执行内容安全策略和依赖安全检查。
  • 应用停用、卸载、权限变化或用户退出时,清理本地会话。
  • 后端服务只信任平台网关注入并验证过的上下文,不信任前端自行传入的 userIdworkspaceId

旧外部入口被拒绝

若启动提示“旧签名启动应用必须创建环境托管应用新版本”,或授权提示“外部托管应用必须使用自己的后台授权”, 先检查安装锁定的平台应用版本是否仍为 TRUSTED_EXTERNAL_APP。定义或版本创建成功不等于当前启动链路支持它。 按 迁移历史外部应用 更新源码、入口、SDK 和完整 Bundle 版本链;不要改成普通外链后继续申请平台 token。

环境配置读取或版本路径校验失败

如果 platform-app workspace list 只返回 /index.html,使用 platform-app workspace launch-context <resourceLocator> --workspace-id <workspaceId> --json 取得该安装的完整 accessUrl。如需检查准确版本部署或跨工作区分享,分别使用 platform-app version addressplatform-app entry,见 三类入口查询

检查实际入口同源的 /.well-known/baijimu-platform-application.json 是否可通过 HTTPS 直接读取, 并确认应用身份和精确 origin 与当前版本一致,SDK 7 的配置合同为 2.0.0。构建归档不能覆盖配置路径,不能把 API 或授权地址从 URL 参数补入。 出现 404、NoSuchKey 或返回 HTML 时,先区分入口类型:

  • 历史 STATIC_SPATRUSTED_EXTERNAL_APP:按完整迁移流程创建 ENVIRONMENT_HOSTED_APP 新版本并升级 Bundle。无需为旧站点追加配置,也无需自行执行站点部署。
  • 已安装的 ENVIRONMENT_HOSTED_APP:从当前安装返回的 accessUrl 访问,核对版本是否已升级、资源台账是否已验证、托管物化是否完成,再排查平台生成配置的步骤。

不要把旧站点的 404 直接解释为 CLI 缺少“配置托管入口”的命令;也不要增加硬编码网关、授权地址、公共 SaaS 默认地址或旧配置缓存。

授权页提示缺少参数

检查参数是否写在 Hash Router 路由后:

正确:https://console.baijimu.com/#/platform-app-authorize?installId=...
错误:https://console.baijimu.com/?installId=...#/platform-app-authorize

分享入口提示需要安装 Bundle

这是预期的授权边界,不是平台应用缺少单独授权。确认分享地址使用 /bundle-app/{bundleId}/{platformAppId},选择正确工作区,并让工作区所有者或管理员安装提示的 Bundle。平台应用不能脱离 Bundle 单独安装。

redirectUri 不合法

检查协议、域名和端口是否与环境托管后的实际入口同源,并核对同源配置的 applicationOrigin;SDK 7 新部署不含 releasePath。清单中的 /index.html 是构建产物内路径,不能直接充当授权回跳 URL,也不能用外部域名替换托管入口。

缺少 PKCE verifier

通常是授权前没有保存 verifier、回跳进入了不同浏览器会话,或者应用刷新逻辑提前清理了 sessionStorage。重新开始授权并保证同一浏览器会话完成回跳。

state 校验失败

停止兑换 token。检查是否同时发起了多个授权请求、多个安装共用了同一个 storage key,或者回跳参数被路由层覆盖。

授权回跳后提示缺少 installId

先查看平台安装记录返回的 accessUrl,确认平台已在托管入口中追加 installId。如果首次跳转有该参数、授权回跳后却 消失,通常是应用自行执行了类似 history.replaceState({}, "", location.pathname + location.hash) 的清理逻辑, 把整个查询串连同 installId 一起删除了。

不要为此增加缓存态 installId 或从其他字段猜测安装身份。环境托管应用必须让 @baijimu/platform-application-sdk 完成回跳清理;SDK 只删除一次性的 codestate,保留入口身份参数。 迁移旧项目时,应同时删除自实现的 PKCE、token 缓存和 Gateway client,避免两套状态机竞争。

token 兑换失败

依次确认:

  1. code 尚未使用且没有过期。
  2. installId 与发起授权时一致。
  3. codeVerifier 与原始 challenge 匹配。
  4. 请求体字段使用 codecodeVerifier

平台切换账号后应用仍是旧用户

先核对部署产物使用的 SDK 版本。SDK 6.0.0 以前会复用应用 origin 的持久化会话,平台与应用域名的 存储不会因另一边退出自动同步。升级 SDK、删除应用自实现缓存并重新构建、创建应用版本、升级 Bundle,再重新打开应用验证。 不要把 token 的有效期当成当前平台身份的证明,也不要通过修改 userId 参数补偿错误身份。

SDK 6.0.0 新开或刷新重新授权;已打开页面的即时账号同步需要平台会话联动。排查时分别记录平台身份、 应用授权返回身份、应用版本和打开时间,不记录完整 token。

接口返回无权限

不要立即重新登录。先区分:

  • App Gateway 明确拒绝会话,SDK 已清空 getSession():重新授权。
  • 后端返回合法 CModel UNAUTHORIZED:保留登录会话并展示业务错误;HTTP 401 本身不能替代 SDK 的会话判断。
  • 模块方法未声明:创建包含正确最小权限的平台应用新版本。
  • 工作区未安装依赖能力:修复安装或接口绑定。
  • 用户没有目标业务权限:由业务权限管理员处理。
  • 后端服务异常:查看目标服务日志和追踪信息。
  • 安装或升级未确认跨 Bundle 方法:重新执行预览,核对精确清单后再确认;不要复用旧预览。

排障时保留 installIdruntimeAppId、平台应用版本号、模块 service、方法名和平台 返回的公开错误信息;不要保存完整 token。

本页内容