必须用 composer config -g github-oauth.github.com 写入全局配置,因 GitHub API 元数据请求发生在安装前全局解析阶段,项目级配置、手动编辑 auth.json 或 http-basic 均无效;字段名、域名、权限(至少 repo)须严格匹配,否则静默失败。

必须用 composer config -g github-oauth.github.com 写入全局配置,其他方式基本无效——GitHub API 的元数据请求发生在安装前的全局解析阶段,此时项目级配置、auth.json 手动编辑、http-basic 都还没被加载。
为什么 composer config -g 是唯一可靠入口
Composer 解析依赖树、查 tag、读远程 composer.json 时,根本没进入项目目录,也就不会读取项目根目录下的 auth.json。只有 -g 写入的全局配置,才会在链路最前端生效。
- 漏掉
-g参数 → token 只进当前项目的composer.json的config字段,对 GitHub 元数据抓取完全无感 - 手动改
~/.composer/auth.json→ JSON 格式错一个逗号、权限不是600、属主不对,Composer 都会静默跳过 - CI 环境中只挂载
auth.json→ 若未清理旧缓存或未设COMPOSER_AUTH,仍可能复用未认证的响应头
github-oauth 字段名和域名不能写错
字段名大小写敏感、嵌套层级固定:github-oauth 不是 github_oauth 或 githubAuth;域名必须是 github.com(GitHub Enterprise 要换成对应实例域名,如 git.example.com)。
- 写成
api.github.com、www.github.com、https://github.com→ Composer 不报错,但认证失败,表现为模糊的Could not fetch或伪装成 404 的 401 - 字段名拼错或嵌套错层 → 配置被忽略,
composer config -g github-oauth.github.com查不到值,输出为空 - GitLab / Bitbucket 同理:GitLab 必须用
gitlab-token+ 完整协议域名(如https://gitlab.example.com),Bitbucket 必须用bitbucket-oauth+bitbucket.org
Token 权限和类型必须匹配场景
GitHub 私有仓库必须用 classic 类型 token,且至少勾选 repo(它包含 public_repo 和 private_repo);read:packages 和 delete:packages 仅在使用 GitHub Packages 时需要。
- fine-grained token 当前主流 Composer 版本支持不稳定,不建议用于生产
- 用账号密码或 SSH key → GitHub 已弃用密码认证,SSH 只影响
git clone,不影响 Composer 的 HTTPS API 请求 - CI 中别硬编码 token 到
auth.json文件再挂载 —— 更安全的是运行时注入COMPOSER_AUTH环境变量,格式为{"github-oauth":{"github.com":"ghp_xxx"}},注意 shell 中双引号要转义
验证是否真生效的实操方法
光看 composer config -g github-oauth.github.com 输出 *** 不代表能用,得触发一次真实请求并观察行为。
- 加
-v运行composer update,搜索日志里是否有Authorization: Bearer ghp_—— 没有就说明域名没匹配上或配置没加载 - 临时删掉项目级
auth.json,避免它覆盖全局配置;CI 中务必确保该文件不存在或已重命名 - 执行
composer clear-cache,否则 Composer 可能复用之前失败的未授权响应缓存 - 若仍失败,加
--no-auth强制跳过认证,确认是不是认证环节的问题,而非网络或包地址本身
最容易被忽略的是:配置写对了,但 Composer 在拉取前已经缓存了失败响应;或者 CI job 中既写了 auth.json 又设了 COMPOSER_AUTH,而前者存在导致后者被跳过。调试时优先清缓存、删项目级 auth.json、再用 -v 看请求头。











