From 438a4d72f8ea58ffcf7ec4595909ec0bd33bc66b Mon Sep 17 00:00:00 2001 From: "2570050763@qq.com" <2570050763@qq.com> Date: Fri, 18 Sep 2026 14:47:30 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E8=AE=B0=E5=BD=95=20Gitea=20OAuth=20to?= =?UTF-8?q?ken=201=20=E5=B0=8F=E6=97=B6=E8=BF=87=E6=9C=9F=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E9=A6=96=E6=AC=A1=E6=8E=A8=E9=80=81=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E7=9A=84=E6=A0=B9=E5=9B=A0=E4=B8=8E=E4=BF=AE=E5=A4=8D=E6=96=B9?= =?UTF-8?q?=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/OPERATIONS.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/docs/OPERATIONS.md b/docs/OPERATIONS.md index 4743a91..501f68b 100644 --- a/docs/OPERATIONS.md +++ b/docs/OPERATIONS.md @@ -96,3 +96,55 @@ - **上游公网 HTTP**:上线阻断,待加密 + 来源限制 + 外部复测(`DEPLOYMENT.md` §4)。 - **音频容量/保留/清理参数**:待用户确认(§5)。 - **备份失败通知渠道 / 是否降权**:待用户确认(§6)。 + +## 8. Git 推送凭据:Gitea OAuth token 1 小时过期导致「首次推送必失败」(已修复) + +### 8.1 现象 + +推送时第一次总是失败,重试第二次才成功: + +``` +remote: Verify +fatal: Authentication failed for 'http://rand.team:44000/Kaotings/www_site.git/' +``` + +### 8.2 根因(上游 Gitea token 有效期 + GCM 缓存) + +- 上游 Gitea(`rand.team:44000`)签发的 OAuth token 是一对 JWT,解码 payload 可见: + - access token:`{"gnt":2,"tt":0,"exp":iat+3600}` → **仅 1 小时有效** + - refresh token:`{"gnt":2,"tt":1,"exp":iat+2628000}` → 30 天有效(每次刷新会轮换) +- Git Credential Manager 把 access token 缓存进 Windows 凭据管理器,而它对 generic OAuth 主机**无法感知 token 过期时间**,于是闲置超过 1 小时后: + 1. 第一次推送 → GCM 返回已过期的 access token → 服务器拒绝(`remote: Verify`); + 2. GCM 删除该缓存凭据; + 3. 第二次推送 → 缓存已空 → GCM 用 refresh token 静默换新 token → 成功。 + +即:不是服务器故障,也不是密码错误,而是「1 小时 token + 无过期感知的缓存」。 + +### 8.3 解决方式(已在本机实施) + +新增凭据助手 `C:/Users/kts/.git-credential-kaotings.mjs`,改为**每次都用 refresh token 换取新 access token**,并在本地记录过期时间提前 5 分钟刷新,从而第一次推送即成功。 + +关键配置(**顺序很重要**):git 的 helper 按 `系统 → 全局 → 仓库` 顺序追加,空值 `helper =` 会清空此前累积的列表。系统级 `C:/Program Files/Git/etc/gitconfig` 中存在 `helper = manager`(修改它需管理员权限),因此必须在全局配置 `C:/Cadence/SPB_Data/.gitconfig` 里先重置再排序: + +``` +[credential] + helper = + helper = !node C:/Users/kts/.git-credential-kaotings.mjs + helper = manager +``` + +- 助手只响应 `host=rand.team:44000`,其它主机静默退出并继续交给 GCM(GitHub / Azure DevOps 等不受影响)。 +- 长期 refresh token **只存于 Windows 凭据管理器**(DPAPI 保护);本地缓存 `~/.kaotings-git-token.json` 只存 1 小时的 access token;刷新时轮换得到的新 refresh token 自动回写凭据管理器。 +- 手动兜底(不依赖上述配置,例如换机器时): + +``` +git -c credential.helper= -c credential.helper="!node C:/Users/kts/.git-credential-kaotings.mjs" push origin +``` + +- 换新机器/新环境:仍需先走一次浏览器 OAuth(GCM),拿到 refresh token 后本助手才有凭据可用。 + +### 8.4 验证记录 + +- 手动把缓存 access token 置为已过期后,单次 `git push` 直接成功(日志显示助手先执行并刷 token,无 401)。 +- 非目标主机(如 `example.com`)调用助手无输出、正常放行给 GCM。 +- 轮换后 refresh token `iat` 更新且已写入凭据管理器。