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

安全与故障排查

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

安全要求

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

旧外部入口被拒绝

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

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

检查实际入口同源的 /.well-known/baijimu-platform-application.json 是否可通过 HTTPS 直接读取, 并确认应用身份、origin 和 releasePath 与当前版本一致。构建归档不能覆盖配置路径,不能把 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 不合法

检查协议、域名和端口是否与环境托管后的实际入口同源,并核对同源配置的 applicationOriginreleasePath。清单中的 /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

接口返回无权限

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

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

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

本页内容