07 · 常见问题与排错
错误码总表
verifyWsa 抛的 WsaVerificationError.code
| code | 常见原因 | 怎么排查 |
|---|---|---|
InvalidSignature |
密钥错、令牌被篡改、Tier1/Tier2 用错密钥 | 确认后端用的密钥与注册/分发的一致;per-app 密钥原样字符串传入,不要 hex 解码 |
WrongAudience |
audience 与令牌 aud 不一致 |
audience 必须精确等于注册 URL 的 host(如 app.example.com),不含端口/协议 |
WrongIssuer |
issuer 配置被改 |
保持默认 gptbots-workspace |
Expired |
令牌超 5 分钟、服务器时钟偏差 | NTP 同步服务器时钟;wsa 是一次性引导令牌,别缓存后再用 |
NotYetValid |
iat/nbf 在未来 |
通常是签发方/校验方时钟严重不同步 |
MissingClaim |
缺 exp/sub/role/workspace_id |
正常平台令牌不会缺;出现说明令牌来源可疑 |
UnsupportedAlgorithm |
alg 不在白名单 |
默认仅 HS256;RS256 需显式 algorithms:['RS256'] + publicKey |
InvalidToken |
令牌为空/结构非法/被截断 | 检查前端是否正确取到完整 wsa,URL 是否被中间层改写 |
/token 换取阶段(拉式)
| code | 含义 | 触发条件 |
|---|---|---|
403209 |
Invalid grant | code 缺失、过期或已被使用(重放)。code 只能用一次 |
403210 |
Invalid verifier | PKCE codeVerifier 与发起时的 code_challenge 不匹配 |
推式 sign-token(由工作空间前端调用,了解即可)
| code | 含义 | 触发条件 |
|---|---|---|
40000 |
Parameter error | URL 不在册、auth_mode 不是 workspace_account |
40100 |
Permission deny | 未登录或会话失效 |
40105 |
Require member of project | 点击人不是该工作空间的成员 |
40320 |
Member not found | 账号被注销/删除 |
FAQ
Q:我该选推式还是拉式?
A:入口在工作空间「扩展」页里、想做「内嵌应用」→ 推式(最简单)。若你的应用是独立站点、想放「用 GPTBots 登录」按钮 → 拉式(M-Auth,更安全,wsa 不进浏览器)。见 02。
Q:能不能在前端直接解 JWT 拿用户信息?
A:可以解开看,但不能当可信身份——没有密钥无法验签,payload 可被伪造。任何授权判断必须以后端 verifyWsa 结果为准。见 05 §5。
Q:wsa 过期了怎么办?
A:wsa 只是一次性引导令牌(5 分钟)。落地时验一次、换成你自己的会话,之后都用你的会话,不要再依赖 wsa。用户下次从扩展页点开会拿到新的 wsa。
Q:落地页 consumeHandoff 抛「no handoff token present」?
A:说明当前 URL 没有 ?wsa=——可能是用户直接访问、或 wsa 已被上一次成功交换抹除。区分「首次带令牌落地」与「普通访问」,后者走你自己的登录/匿名分支。
Q:拉式登录回调报 StateMismatch / MissingRequest?
A:MissingRequest = 没先在同一浏览器会话调 startWorkspaceLogin(PKCE verifier 存在 sessionStorage,换标签页/清了存储就会丢)。StateMismatch = 回调 state 与存储的不一致(CSRF 保护),确认没跨设备/跨会话。
Q:拉式登录报 CryptoUnavailable?
A:PKCE 需要 Web Crypto,只在安全上下文(HTTPS 或 localhost)可用。用 HTTPS 或本地 localhost 调试。
Q:redirect_uri 报 invalid_request / 回到组织选择页?
A:redirect_uri 的 scheme + host 必须与 client_id(注册 URL)精确相同。https 应用不能配 http 回调;host 必须一致。平台绝不跳到未校验地址,所以会回组织选择页带 ?error=invalid_request。
Q:per-app 密钥怎么当 HMAC key?要不要 base64/hex 解码?
A:原样字符串传入(SDK 与平台均按 UTF-8 字节直接作 HMAC key)。Tier 2 密钥形如 wext_+64 hex,整串就是密钥,不要再解码。
Q:CommonJS 项目能用 SDK 吗?
A:SDK 是 ESM。CJS 项目用动态 import(),或把相关模块改为 ESM。
Q:图标/名称怎么改?
A:Tier 2 在空间管理里编辑;Tier 1 联系平台运维改字典条目。
Q:管理员停用了我的应用会怎样?
A:组织管理员在空间管理里可停用应用(含平台公共应用在本组织的可见性)。停用后该组织成员在扩展页看不到入口,平台也不会再为该组织签发 wsa(推式与拉式都拒绝)。
联调清单
-
audience== 注册 URL 的 host(最常见的WrongAudience来源) - 后端密钥与注册/分发一致,且只在后端
- 服务器时钟 NTP 同步(
Expired/NotYetValid多因时钟) - 落地后
history.replaceState抹除wsa/code - 换成自有会话,后续请求不透传
wsa - 拉式:HTTPS/localhost 安全上下文;
redirect_uri与client_id同域 - 多租户按
workspace_id隔离
