NapCat 二维码刷新失效 (NapCat Stale QR Refresh Failure)
1. 现象
NapCat WebUI 登录页(/webui/qq_login)点「刷新二维码」,页面毫无反应。二维码不变,扫码也无效。接口不报错,浏览器控制台干净。
2. 根因
NapCat 的登录状态机卡死,RefreshQRcode 变成了空操作。
QQ 登录二维码是一次性的:NapCat 向腾讯要一次码,之后一直复用。重启后状态机会重新走一遍登录流程,才会再次要码。
本例中账号 08:15 快速登录失败后进入扫码模式,之后 9 小时无人扫码,状态机挂起。此时:
| 接口 | 返回 | 含义 |
|---|---|---|
POST /api/QQLogin/RefreshQRcode | {"code":0,"data":null,"message":"success"} | 返回成功但什么都没做 |
POST /api/QQLogin/GetQQLoginQrcode | {"code":0,"data":{"qrcode":"https://txz.qq.com/p?k=..."}} | 返回的是冻结的旧码 |
POST /api/QQLogin/CheckLoginStatus | {"isLogin":false,"qrcodeurl":"<同一个旧码>"} | 证实码没换 |
关键点:接口返回 code:0 / success 不代表刷新成功。 前端 refreshQRCode() 是 fire-and-forget(await a.post(...) 不取返回值),所以失败也不会在任何地方报出来。
注意二维码不是图片,而是一个 URL(https://txz.qq.com/p?k=xxx),由前端本地渲染成 QR。所以看返回体积小(42 字节)是正常的,不是异常信号。
3. 判定方法
看 k= 参数变不变。不变 = 卡死。
# 取到 qrcode URL
curl -s -X POST -H "Authorization: Bearer $C" \
http://127.0.0.1:6099/api/QQLogin/GetQQLoginQrcode
# 点一次刷新,再取一次。k= 相同即卡死。
curl -s -X POST -H "Authorization: Bearer $C" \
http://127.0.0.1:6099/api/QQLogin/RefreshQRcode也可直接看服务日志,重启后会出现新的「二维码解码URL」行:
sudo journalctl -u napcat-<账号>.service --since "1 min ago" | grep "二维码"4. 解决
sudo systemctl restart napcat-<账号>.service重启后 RefreshQRcode 恢复正常,k= 每次刷新都变。
验证:
# 重启后连点两次刷新,k= 应该不同5. 附:NapCat WebUI 认证方式(排查时需要)
WebUI 的凭据不是直接用 token,要换一次:
# 1. 算 hash:SHA256(token + ".napcat")
H=$(printf "<webui_token>.napcat" | sha256sum | cut -d' ' -f1)
# 2. 换 Credential
curl -s -X POST -H "Content-Type: application/json" \
-d "{\"hash\":\"$H\"}" http://127.0.0.1:6099/api/auth/login
# -> {"code":0,"data":{"Credential":"eyJ..."}}
# 3. 后续请求带 Authorization: Bearer <Credential>token 在 NapCat/config/webui.json,找不到时可在启动日志里 grep token=。
前端调用链(从 static/assets/*.js 反查):
refreshQRCode() { await a.post("/QQLogin/RefreshQRcode") } // 不取返回值
getQQLoginQrcode() { return (await a.post("/QQLogin/GetQQLoginQrcode")).data.data.qrcode }
checkQQLoginStatus() { return (await a.post("/QQLogin/CheckLoginStatus")).data.data }
loginWithToken(t,r) { const n = SHA256(t + ".napcat"); await le.post("/auth/login", {hash:n, totpCode:r}) }另外 POST /api/QQLogin/RestartNapCat 也是 NapCat 自带的恢复入口,效果近似重启。
6. 识别要点
- NapCat 登录页刷新无反应 → 先看
k=变不变,别怀疑网络和 nginx。 - 登录二维码本身约 2 分钟就过期。只要长时间没人扫,就会进入这个卡死态。
- 接口返回
success≠ 真的刷新了。前端是 fire-and-forget,不会报错。 - 一般性结论:NapCat 长时间停留在扫码登录页,刷新会失效,重启服务是标准解法。
7. 相关笔记
- NapCat 与 Stapxs QQ Lite 部署排障 (NapCat & Stapxs QQ Lite Troubleshooting)
- QQ 机器人协议端选型 Mirai 已死与 NapCat 掉线根因 (QQ Bot Protocol Backend Mirai Deprecation and NapCat Disconnect Root Cause)
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/AI apps