[Bug] BigModel OAuth 登录失败:浏览器授权成功但服务端 authCode 兑换失败(poll 3004 invalid_flow,关联 #705)
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 22
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
提交前确认 · Pre-submission checklist
- 我已搜索过现有 issue,确认这不是重复 / I searched existing issues and confirmed this isn't a duplicate.
- 我已阅读 CONTRIBUTING.md / I've read CONTRIBUTING.md.
问题类别 · Category
账号 / 登录 · Account / Login
涉及的 Agent 框架 · Agent framework
ZCode Agent(自研)
严重程度 · Severity
阻塞使用 · Blocking (无法使用核心功能 / core function unusable)
复现频率 · Reproducibility
必现 · Always
问题描述 · Description
摘要:BigModel OAuth 登录在浏览器侧授权完全成功后,服务端 authCode 兑换失败,flow 被判死(3004 invalid_flow)。通过协议级独立复现排除了桌面端参与,失败发生在 zcode.z.ai 后端对 bigmodel 的服务端兑换环节。
- 从 v3.11.2(2026-09-07 首次尝试,当天 24 次)到 v3.12.3,累计 30+ 次登录尝试,无一成功;本地
credentials.json从未写入过任何 oauth token(仅oauth:login_attribution)。 - 浏览器侧流程全部正常:
bigmodel.cn/login?appId=zcode弹出「ZCode 授权请求」确认页 → 点「同意」→ 显示「授权成功」→ 落地页zcode.z.ai/app/oauth/login收到authCode+state。 - 失败点:落地页向
GET /api/v1/oauth/cli/callback/bigmodel?authCode=…&state=…兑换时服务端拒绝(400,通用错误页「Authorization Failed / 授权失败」),flow 随即被服务端判死;桌面端轮询 ~5s 后收到ApiError: invalid_flow。 - 账号为微信注册(用户名为随机字符串样式,疑似未绑定手机号)——不确定是否相关,供定位参考。
与 #705 的关系:同为 BigModel 登录失败、同落在后端兑换环节。但 #705 诊断为「Web 轮询网桥与 DeepLink 回调双重核销竞态」;本例在桌面端完全离场(无 DeepLink 回调,应用日志证实)的情况下,仅落地页网桥单次兑换仍然失败——说明至少还存在服务端兑换路径自身的问题,不是(只是)竞态。与 #116(zai provider 的 IPv6/undici 超时)、#337(CLI init 404)为不同环节。
复现步骤 · Steps to reproduce
A. 桌面端路径(必现)
- 全新安装 ZCode v3.12.3(.deb → /opt/ZCode),清除用户数据(
~/.zcode、~/.config/ZCode)。 - 欢迎页点击「连接 BigModel 继续使用」。
- 默认浏览器打开
bigmodel.cn/login?appId=zcode&redirect=<落地页>&state=…。 - 已有 bigmodel 会话自动弹出「ZCode 授权请求」确认页,点击「同意」。
- bigmodel 显示「授权成功」,跳转落地页并携带
authCode+state。 - 落地页显示「授权失败 / 授权过程中出现错误,请返回 ZCode 重试」。
- 桌面端日志:
oauth.pollPendingOAuth FAIL ApiError: invalid_flow(约 5 秒后),界面显示「登录失败,请重试」。
B. 协议级独立复现(无桌面端参与,同样失败)
1. POST https://zcode.z.ai/api/v1/oauth/cli/init
Authorization: Bearer <随机32字节hex>
{"provider":"bigmodel"}
→ {"code":0,"data":{"flow_id":"f177a…","authorize_url":"https://bigmodel.cn/login?appId=zcode&redirect=…","poll_interval_sec":2,"expires_at":…}} # 正常
2. 浏览器打开 authorize_url → 「同意」→「授权成功」→ 落地页收到 authCode+state # 正常
3. 落地页向 /api/v1/oauth/cli/callback/bigmodel?authCode=…&state=… 兑换
→ 失败,落地页显示「授权失败」 # ← 失败点
4. 独立轮询器 GET /api/v1/oauth/cli/poll/<flow_id>(Bearer 同 poll token)
→ 持续 {"code":0,"data":{"status":"pending"}},随后终态 {"code":3004,"msg":"invalid_flow"}
期间桌面端日志无任何 deep-link / oauth 回调事件 # 排除双重核销竞态
期望表现 · Expected behavior
落地页网桥兑换 authCode 成功 → poll 终态返回 ready/token → 桌面端完成登录并同步账号信息与 Coding Plan 权益。
实际表现 · Actual behavior
- 落地页:红色 ✕「授权失败 / 授权过程中出现错误,请返回 ZCode 重试」。
- 桌面端:「登录失败,请重试」,日志
oauth.pollPendingOAuth FAIL ApiError: invalid_flow。 - flow 终态
{"code":3004,"msg":"invalid_flow"};账号始终无法登录,无法使用已订阅的 GLM Coding Plan。
ZCode 版本 · ZCode version
v3.12.3-7463(.deb)。v3.11.2(2026-09-07/08 日志与浏览器历史证实)起同样失败。
设备 / 系统 / 浏览器 · Device / OS / Browser
x86_64 Linux / Ubuntu 26.04 LTS / Google Chrome(系统默认浏览器)。网络:智谱系域名(z.ai / bigmodel.cn)直连,无代理介入;时钟已同步;api.z.ai TCP 握手 ~52ms。
截图 / 录屏 / 日志 · Screenshots / Recordings / Logs
桌面端日志(v3.12.3,一次典型失败,间隔 ~5s):
[12:47:56] [oauthService][trace:OAuth polling flow started] {"expiresInMs":299327,"pollIntervalMs":2000,"provider":"bigmodel"}
[12:47:56] [rpc:call] oauth.startOAuthWithPolling OK (69.0ms)
[12:48:02] [rpc:call] oauth.pollPendingOAuth FAIL (73.6ms) {"name":"ApiError","message":"invalid_flow"}
浏览器历史(Chrome urls 表,同一尝试的完整跳转链,参数已截断):
13:03:25 https://bigmodel.cn/login?appId=zcode&redirect=https%3A%2F%2Fzcode.z.ai%2Fapp%2Foauth%2Flogin%3F…&state=6e1ae…
13:03:29 https://zcode.z.ai/app/oauth/login?redirect=zcode%3A%2F%2Foauth%2Fcallback&app_version=3.12.3&authCode=ACKiaP…&state=6e1ae…
(无后续 zcode:// 成功回调;落地页渲染「授权失败」)
历史失败统计(旧日志档案): 2026-09-07 单日 24 次 startOAuthWithPolling,全部以 invalid_flow 失败;09-08、09-19(3.11.2 与 3.12.3)同样。
回调端点行为(外部探测): 对 /api/v1/oauth/cli/callback/bigmodel 传任意无效 authCode/state 均返回同一张通用错误页(HTTP 200/400,无错误码区分),真实 authCode 的失败无任何可区分信号——建议后端在响应中区分「state 不存在 / authCode 已消费 / 服务端兑换上游错误」并记录服务端日志。
如需要账号标识(微信注册账号)用于服务端排查,可私下提供。
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the /api/v1/oauth/cli/init, /api/v1/oauth/cli/callback/bigmodel, and /api/v1/oauth/cli/poll/{flow_id} endpoints and compare the reported request sequence with server-side logs. Check whether state validation, authCode consumption, or the upstream exchange rejects the flow. Done means the callback succeeds and polling returns ready with a token, allowing desktop login and account synchronization.
Written by the indexing model from the issue text.
Assessment
- Domain
- api, authentication, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100