composer install 报错“invalid credentials”是github令牌权限不足,需检查pat是否包含read:packages(私有packages)或repo(私有git仓库)等必要scope,并确认token未过期、未被撤销、归属正确账号及fine-grained token已显式授权对应仓库。

Composer install 报错 “Invalid credentials” 是 GitHub 令牌权限不足
这不是网络或配置文件语法问题,而是你提供的 GitHub Personal Access Token(PAT)缺少必要 scope。Composer 在拉取私有仓库时会用该 token 认证,若 token 没开 read:packages 或 repo(取决于仓库类型),就会返回 Invalid credentials,且错误信息不提示具体缺哪个权限。
- 私有 GitHub Packages (npm/docker/package-registry):必须启用
read:packages+delete:packages(如需 publish)+write:packages - 私有 Git repo(通过 git@github.com 或 https URL):必须启用
repo(否则 clone 失败) - 使用 GitHub App 或 OAuth token?Composer 不支持,只认 PAT
如何验证和更新 GitHub token 权限
别删旧 token 重生成——先检查它是否还在生效、缺什么 scope。访问 https://www.php.cn/link/f4380fd29ac34f2610014e8361d088fb,点进你的 token,勾选缺失项再「Update token」即可,无需改 Composer 配置。
- 确认 token 是否已过期:GitHub PAT 默认无过期时间,但手动设置了过期的会被拒
- 确认 token 是否被 revoke:页面显示 “Revoked” 就得新建
- 确认 token 是否绑定到了正确账号:私有库属于组织?token 必须由有该组织访问权限的成员生成
- 如果用的是 fine-grained token:必须显式添加对应 organization 和 repository 的访问权限,不能只选 “All repositories”
Composer 中 token 的写法和存储位置要匹配认证方式
GitHub 私有库常用两种接入方式,token 放的位置和格式完全不同,混用必报错。
- 走
https://github.com/xxx/yyy(推荐):在auth.json里配github.com域名级凭据:{"github.com": {"oauth_token": "ghp_..."}} - 走
git@github.com:xxx/yyy.git(SSH):token 完全无效,应配 SSH key;此时若误配了auth.json,Composer 会忽略它但仍可能因其他原因报 credential 错 -
auth.json路径优先级:项目根目录auth.json>COMPOSER_HOME/auth.json(通常是~/.composer/auth.json)> 全局 config - 敏感操作后建议运行
composer clear-cache,避免旧凭据缓存干扰
调试时别信 “401 Unauthorized” 表面信息
GitHub 返回 401 时,Composer 统一转成 Invalid credentials,但它可能是:token 错、scope 缺、repo 不存在、网络拦截了 GitHub API 域名(比如公司 proxy 拦了 api.github.com)。
- 用
curl -H "Authorization: token ghp_..." https://api.github.com/user直接测 token 是否有效 - 用
curl -H "Authorization: token ghp_..." https://api.github.com/repos/ORG/REPO测是否有该私库读权限 - 开启 Composer 调试:
composer install -v或composer install -vvv,看实际请求的 URL 和响应头 - 注意 GitHub 新增的
token-auth强制要求:2023 年起,所有 HTTPS Git 操作必须用 token,密码认证已弃用
最容易被忽略的是 fine-grained token 的 repository 权限粒度——它不像 classic token 那样一键给全 repo 权限,必须手动添加每个要用的私有库,漏一个就 401。










