GitHub API 401 Unauthorized 是因 Composer 未携带有效 token 认证凭据,非网络问题;需确认 token 已通过 composer config -g --auth github-oauth.github.com 正确写入、权限含 read:packages 和 public_repo、auth.json 位置正确且权限为600,并清除缓存验证。

GitHub API 401 Unauthorized 是 token 没生效,不是网络问题
报错 Could not fetch https://api.github.com/ 401 Unauthorized,基本可以排除代理、DNS 或 SSL 证书问题。这是 GitHub 明确拒绝了未认证请求——Composer 尝试调用 REST API 获取元数据(比如 tag 列表、composer.json 内容),但没带上有效的 Authorization 头。
常见误判:以为是 SSH 密钥没配好,或 git clone 失败连带影响 Composer;其实 Composer 走的是 HTTPS + API 路径,跟 git@github.com 完全无关。只要 composer.json 里依赖项 URL 是 https://github.com/xxx/yyy,或者用了 "type": "vcs" + HTTPS 地址,就一定会触发 API 请求。
- 检查是否真写了 token:
composer config --global github-oauth.github.com应输出一串掩码值(如****-abcd-efgh-ijkl-mnop),空输出说明根本没写进去 - 确认没漏
--auth参数:用composer config -g github-oauth.github.com xxx是错的,必须加--auth才会被识别为认证凭据 - 别信“复制成功”:生成 token 后粘贴进命令时,容易带入不可见空格或换行符,建议用
echo "$TOKEN" | xxd看结尾有没有0a(换行)
token 权限选错会导致 403 或静默失败
GitHub 的 fine-grained token 和 classic token 权限模型不同,但 Composer 只认 scope 名字,不认 UI 分组。只勾 repo 不够,尤其当你依赖的包发布在 GitHub Packages(ghcr.io)或属于启用了 SSO 的组织时。
- 必须勾选:
read:packages(读取所有 packages,含 public/private)、public_repo(访问公开仓库元数据) - 私有仓库必需:
repo(classic)或Contents(fine-grained,read-only 即可) - 组织内私有包 + SSO:缺
read:org会返回 403,且错误信息里不提这个字段,容易卡住 - 不要勾
delete:packages或admin:org—— 权限最小化原则,token 泄露风险直线上升
国内访问慢?先切镜像源,再配 token
镜像源和 GitHub Token 解决的是两类问题:前者绕过 packagist.org 元数据查询和 ZIP 下载路径,后者解决 GitHub API 调用限流。两者不互斥,但顺序很重要——先配镜像,能大幅减少对 GitHub API 的依赖次数。
- 全局切换阿里云镜像:
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ - 单项目配置(推荐 CI 场景):
composer config repo.packagist composer https://mirrors.aliyun.com/composer/ - 镜像生效后,
composer.lock里的 URL 还是旧的,删掉重装更稳妥:rm composer.lock && composer install - 注意:phpcomposer.com 已停更,别用;HTTP 镜像地址会被新版 Composer 拒绝,必须用 HTTPS
auth.json 位置和权限经常被忽略
Composer 加载认证配置有明确优先级:命令行参数 > 全局 ~/.composer/auth.json > 项目根目录 auth.json。但很多人把文件放错位置,或 chmod 错了导致读不到。
- Linux/macOS 全局路径:
~/.composer/auth.json(不是~/.composer/config.json) - Windows 全局路径:
%APPDATA%\Composer\auth.json - 文件权限必须是
600,且属主是当前运行 composer 的用户(比如 root 写的,普通用户执行会静默跳过) - 项目级
auth.json只在当前目录执行composer install时临时生效,但若全局已配,它会被覆盖——调试时建议先composer config -g --unset github-oauth.github.com清掉全局再测


















