ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Copilot API认证体系详解:GitHub设备码与OAuth令牌刷新完整机制

Copilot API认证体系详解:GitHub设备码与OAuth令牌刷新完整机制

【免费下载链接】copilot-api

GitHub Copilot, OpenAI Codex, OpenCode Go, and third-party AI provider gateway with OpenAI and Anthropic API compatibility.

项目地址:https://gitcode.com/gh_mirrors/copilot/copilot-api
点击查看免费下载

copilot-api 是一个支持 GitHub Copilot、OpenAI Codex、OpenCode Go 及第三方 AI provider 的 API 网关,提供 OpenAI 与 Anthropic 双协议兼容。本文带你完整读懂它的认证体系:GitHub 设备码(Device Code)登录如何工作、Copilot 访问令牌如何自动刷新、Codex OAuth 令牌轮换如何避免并发冲突,帮助新手一次配好并长期免打扰使用。

📋 认证体系全景:三条登录路径

copilot-api 的认证围绕三类凭证展开:

凭证用途获取方式刷新机制
GitHub token访问 GitHub 与换取 Copilot 令牌设备码登录(RFC 8628)长期有效,一次登录长期复用
Copilot access token实际调用 Copilot 模型用 GitHub token 交换后台循环按refresh_in自动刷新
Codex 凭证调用 OpenAI CodexOAuth 2.0 授权码 + PKCErefresh_token轮换式自动刷新

登录成功后,桌面端 Dashboard 会显示当前 Copilot 套餐(如 individual / Business)、配额用量与网关服务地址,认证状态一目了然:

📝 GitHub 设备码登录:三步完成授权

GitHub 设备码流程遵循 OAuth 2.0 Device Authorization Grant(RFC 8628),特别适合没有浏览器回调环境的终端场景。执行copilot-api auth login --provider copilot后会依次完成三步(入口逻辑见 src/lib/token.ts):

第一步:申请设备码

客户端向/login/device/code发起请求,携带client_id与权限 scope(URL 配置见 src/lib/api-config.ts),服务端返回一组凭证:

  • user_code:展示给用户、用于浏览器输入的短码
  • device_code:客户端轮询时使用的内部凭证
  • verification_uri+expires_in:授权页面地址与有效期

实现见 src/services/github/get-device-code.ts。

第二步:浏览器中完成授权

终端会打印类似Please enter the code "XXXX-XXXX" in https://github.com/login/device的提示,你在浏览器打开该地址、登录 GitHub 并输入 user code 确认授权即可。此步骤完成后,GitHub 侧才会向轮询端点放行令牌。

第三步:轮询换取访问令牌

客户端按interval间隔向/login/oauth/access_token轮询(grant_type 为urn:ietf:params:oauth:grant-type:device_code)。src/services/github/poll-access-token.ts 中有几个值得注意的工程细节:

  • authorization_pending:用户还没在浏览器确认,继续按间隔轮询;
  • slow_down:GitHub 要求放慢节奏,每次命中轮询间隔 +5 秒(RFC 8628 第 3.5 节),且取服务端返回interval与本地累加值的较大者;
  • 其他错误:立即终止并抛出GitHub device authorization failed;
  • 网络抖动容错:轮询请求失败(如代理断开连接)只记录警告并继续重试,不会中断登录;超过expires_in才会报device code expired要求重新登录。

拿到的 GitHub token 通过 writeGitHubToken 以受保护权限写入本地凭证文件,下次启动直接读取、无需重复登录。

🔄 Copilot 访问令牌自动刷新机制

GitHub token 只是"入场券",真正调用模型用的是 Copilot 访问令牌,它有效期很短,需要持续换新:

令牌交换:/copilot_internal/v2/token

getCopilotToken 携带 GitHub token 请求该端点,返回token、expires_at与refresh_in(应在多少秒后刷新)。返回体中的endpoints.api被视为令牌路由的权威来源——企业版与商业版账号可能对应不同主机段,以交换响应的端点为准可避免 421 Misdirected Request 问题。

后台刷新循环:提前 60 秒、失败指数退避

runCopilotRefreshLoop 是保活的核心,策略为:

  1. 提前刷新:刷新截止点 = 当前时间 +refresh_in - 60 秒,预留安全缓冲;
  2. 短周期轮询:每 15 秒醒一次检查是否到点,确保系统休眠唤醒后能立刻发现已过期;
  3. 失败重试:刷新失败后 15 秒重试并叠加随机抖动(jitter),延迟逐次翻倍、上限 10 分钟,直到成功;
  4. 成功重置:刷新成功后用新的refresh_in重新计算下一个截止点。

这意味着只要 GitHub 登录有效,Copilot 令牌会永远"无感续杯",客户端调用零中断。

🔐 OpenAI Codex 登录:PKCE 授权码 + 本地回调

Codex 走标准 OAuth 2.0 授权码流程,实现集中在 src/lib/oauth/codex.ts:

浏览器授权 + PKCE 防截获

执行copilot-api auth login --provider codex后,程序随机生成 PKCE 的code_verifier(SHA-256 派生code_challenge,S256 模式)与一次性state,打开auth.openai.com/oauth/authorize授权页。本地在127.0.0.1:1455临时起回调服务接收授权码,并严格校验state防 CSRF;若浏览器无法回调(超时 2 分钟),支持手动粘贴完整回调 URL 或 code 作为兜底。

账号识别与多账号管理

授权码换到的 access token 是 JWT,程序解析其中chatgpt_account_id声明提取账号 ID。凭证存储在codex_credentials.json,最多保存 3 个账号,支持别名与 oauth-accounts 提供的--list/--use/--remove管理,正在使用的账号禁止删除。

refresh_token 轮换下的并发保护

Codex 上游每次刷新都会轮换 refresh_token(旧令牌立即作废),并发刷新会让其中一个调用方失败甚至用旧值覆盖新值。refreshCodexCredentialsOnce 因此做了三层防护:

  • single-flight:以「账号 ID + refresh_token」为键的在途去重,同一时刻只有一个真实刷新请求;
  • 写盘失败补偿:刷新成功但落盘失败时,结果缓存在codexCredentialsPendingPersistence中,重试只补写文件、不再消耗已作废的 token;
  • 文件锁:凭证文件读写加锁,避免多进程互相踩踏。

后台 runCodexRefreshLoop 在令牌过期前 60 秒发起刷新,失败则 15 秒后重试,同样实现无感续期。

🗂️ 凭证安全存储位置

所有凭证默认存放在用户目录下的应用数据文件夹(可通过环境变量COPILOT_API_HOME覆盖),路径定义见 src/lib/paths.ts:

  • ~/.local/share/copilot-api/<app>/github_token—— GitHub 设备码登录结果
  • ~/.local/share/copilot-api/codex_credentials.json—— Codex 多账号凭证
  • ~/.local/share/copilot-api/config.json—— provider 与网关 Key 配置

写入均使用带权限保护的writeProtectedFile,避免同机其他用户读取。CLI 也支持COPILOT_API_GITHUB_TOKEN环境变量注入 token,解析顺序为:--github-token→ 环境变量 → 本地 token 文件。

🖥️ 桌面端与多 Provider 认证

桌面应用把同一套设备码流程封装成图形化体验:device-flow.ts 中每次发起新的登录请求都会中止上一次的轮询,保证只有当前流程能落地凭证;令牌到手后并行校验用户身份与账号类型再写入设置。多 provider 场景下,可在 Providers 面板统一管理 github-copilot、codex 及各第三方 provider 的启用与模型展示:

⚡ 常用认证命令速查

命令作用
copilot-api auth login --provider copilot设备码登录 GitHub,启用 Copilot
copilot-api auth login --provider codex --alias workOAuth 登录 Codex 并设置别名
copilot-api auth codex --list查看已保存的 Codex 账号
copilot-api auth codex --use <alias>切换当前 Codex 账号(需重启服务)
copilot-api auth codex --remove <alias>移除未在使用中的账号

更多细节可参考官方 CLI 指南 docs/guides/zh-CN/cli.md。

小结

copilot-api 的认证体系可归纳为一句话:设备码换取长期 GitHub token,长期 token 驱动后台循环无感刷新短命的 Copilot 令牌,Codex 侧则用 PKCE 授权码配合轮换式 refresh_token 与并发保护实现持久登录。理解这套机制后,无论是排查"登录过期"还是多账号切换,你都能快速定位到对应模块。

【免费下载链接】copilot-api

GitHub Copilot, OpenAI Codex, OpenCode Go, and third-party AI provider gateway with OpenAI and Anthropic API compatibility.

项目地址:https://gitcode.com/gh_mirrors/copilot/copilot-api
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进