bug: 登录状态经常丢失,自安装已经丢失10次,/api/device-link/devices返回401
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 401
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
### 问题描述 / What happened
已经让AI自我检查完了。结论很明确:这是 Cindy 自身的登录刷新与异常恢复问题,不是 Apple ID 登录,也不是你电脑的钥匙串把登录信息弄丢了。
我找到的证据:
- 当前是最新版 Cindy 0.1.50,但今天凌晨 04:16 仍然复现。
- 8 月 7 日至 17 日,日志记录了至少 10 次 `resource-unauthorized-after-refresh` 强制退出,另有一次明确的 `INVALID_REFRESH_TOKEN`。
- 本机加密登录文件一直存在,没有任何 `safeStorage` 解密、加密或写入失败。
- 今天 10:03 重新登录后,加密会话文件正常重写。
- 当前也只有一个 Cindy 主进程,不像是多实例互相覆盖凭据。
最核心的问题是:Cindy 调用 `/api/device-link/devices` 时收到 `TOKEN_EXPIRED`,随后刷新登录令牌;刷新流程返回成功,但该接口重试仍然是 401。Cindy 此时直接把整个账号登录状态清空。今天凌晨的完整过程在 [main-2026-08-17.log]()。
而在 8 月 14 日还出现过另一条更典型的链路:
1. 电脑睡眠或切换网络,DNS、网络请求失败;
2. 登录刷新请求返回状态 0,客户端不知道服务端是否已经轮换令牌;
3. 网络恢复后,旧刷新令牌被服务端判定为 `INVALID_REFRESH_TOKEN`;
4. Cindy 两次重读本地仍找不到新令牌;
5. 直接清空登录状态。
对应证据在 [main-2026-08-14.log]()。
所以最可能是两个缺陷叠加:
- 刷新令牌采用轮换机制,睡眠或网络切换时可能出现“服务端已经消费旧令牌,但客户端没收到新令牌”的情况。
- 设备连接接口刷新后仍返回 401,Cindy 就过于激进地注销整个账号,没有延迟重试、宽限期或只隔离该功能。
你目前的“远程控制”其实已经关闭,但 Cindy 仍在后台请求设备目录,因此用户侧没有明显的开关可以绕过这个触发点。重装应用、清理钥匙串大概率也没用,还可能增加本地数据风险。
可以把下面这段直接发给开发者:
> macOS Cindy 0.1.50 仍可复现登录状态异常。2026-08-17 04:16:22,`/api/device-link/devices` 在 auth refresh 后仍连续返回 `401 TOKEN_EXPIRED`,客户端随后以 `resource-unauthorized-after-refresh` 清空整个登录态。2026-08-14 10:18 另一次在睡眠/断网后出现 `runtime refresh status=0`,网络恢复后旧令牌返回 `INVALID_REFRESH_TOKEN`,日志显示 `no replacement token on disk`,最终 definitive credential failure。8 月 7 日至 17 日共出现至少 10 次同类强制退出。本机 safe-storage 没有任何解密或写入错误。建议检查 refresh-token rotation 的丢响应恢复、token family/旧令牌宽限期、device-link 对新 access token 的验证,以及避免单个资源接口在刷新后一次 401 就触发全局注销。
在修复前,稍微有效的临时办法是通勤或长时间合盖前完全退出 Cindy,到网络稳定后再打开;仅关闭窗口不够。不过这只是减少触发概率,真正问题仍需客户端和认证服务修复。
### 环境 / Environment
- Cindy 版本或 commit / version or commit:所有版本,每次更新后都还存在
- 平台与版本 / platform & OS version:mac os
- 安装方式 / install method: dmg,自动更新
### 复现步骤 / Steps to reproduce
改上电脑一段时间后,会要求重新登录;隔一天或者从家里到公司,又要重新登录。
chatgpt,codex,qoder等等这些ai客户端都不会出现一直要求重新登录的情况,但是cindy甚至一天要登录2次,太麻烦了。
### 日志与截图 / Logs & screenshots
_No response_
Contributor guide
Research direction
Start by tracing the client handling of `/api/device-link/devices` around `TOKEN_EXPIRED`, `resource-unauthorized-after-refresh`, `runtime refresh status=0`, and `INVALID_REFRESH_TOKEN`. Use the referenced 2026-08-17 and 2026-08-14 logs to compare refresh and retry behavior. Done means the reported sleep or network-change scenarios no longer cause an unwarranted loss of the global login state.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- electron, typescript
- Domain
- api, authentication, desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100