github oauth 配置必须写入全局 auth.json 文件而非 composer.json,路径为 ~/.composer/auth.json(linux/macos)或 %appdata%\composer\auth.json(windows),内容为 {"github-oauth": {"github.com": "ghp_abc123..."}},token 需为带 repo 权限的 personal access token。

Composer 用 GitHub Token 是唯一靠谱的绕过限流办法,不用 token 就算走 HTTPS 也扛不住每小时 60 次匿名请求的墙。
github-oauth 配置写在哪?不是 composer.json
这个配置不进项目级 composer.json,而是写进 Composer 的全局 auth 配置文件里——也就是 auth.json。它默认在用户主目录下的 COMPOSER_HOME 目录里(Linux/macOS 是 ~/.composer/auth.json,Windows 是 %APPDATA%\Composer\auth.json)。
- 别手贱往项目
composer.json里塞github-oauth字段,它只认全局auth.json - 如果
auth.json不存在,直接新建一个;如果存在但没github-oauth段,就补上 - 内容长这样:
{ "github-oauth": { "github.com": "ghp_abc123def456..." } } - Token 必须是 Personal Access Token(PAT),且至少勾选
repo权限;read:packages和delete:packages不是必须的
为什么用 github.com 而不是 api.github.com?
Composer 内部做包源解析时,把所有 GitHub 仓库 URL(比如 https://github.com/vendor/package)统一映射到域名 github.com 去查 token,而不是去匹配 API 域名。所以即使你用的是 api.github.com 的请求路径,配置里也得写 "github.com"。
- 写成
"api.github.com"或"https://github.com"都无效 - 大小写敏感:必须小写
github.com - 多个 GitHub 实例(比如 GitHub Enterprise)才需要额外加键,例如
"ghe.example.com"
token 失效或权限不足时的典型报错
错误不会明说“token 错了”,而是伪装成网络或权限问题:
-
Could not fetch https://api.github.com/repos/xxx/yyy/zipball/zzz: Failed to decode response: zlib_decode(): data error—— 实际是 401/403 返回了 HTML 登录页,zlib 解压失败 -
Failed to download vendor/package: The 'https://api.github.com/repos/vendor/package/zipball/...' file could not be downloaded (HTTP/2 403 )—— GitHub 明确拒绝,常见于 token 过期、被删、或没勾repo - 运行
composer install卡住几秒后报超时,其实背后是反复重试 403,直到 Composer 放弃 - 验证是否生效:运行
composer config --global --auth github-oauth.github.com,能回显 token 就说明写对位置了
CI/CD 环境里怎么安全传 token?
本地开发写 auth.json 没问题,但 CI 流水线不能硬编码 token 到代码或配置文件里。
- GitHub Actions:用
${{ secrets.GITHUB_TOKEN }}(自带)或自定义 secret 注入环境变量,再用脚本生成auth.json - GitLab CI:通过
CI_JOB_TOKEN或自定义变量,在before_script里 echo 出auth.json - 注意权限:生成的
auth.json文件权限设为600,否则 Composer 会拒绝读取(报auth.json is not readable) - 别用
composer config --global --auth在 CI 里动态设,它会把 token 写进日志(除非你关掉命令回显)
Token 本身不是万能钥匙——它解决的是「认证后限流」问题,但如果包依赖大量私有 repo、或者用了 repositories 自定义源又没配好认证,照样会卡住。真正麻烦的从来不是加一行配置,而是搞清哪一层丢了凭证。










