Composer报401是因为未正确注入认证凭据,需用composer config -g --auth github-oauth.github.com 全局配置GitHub令牌(域名必须为github.com),并确保repositories中私有源类型正确(如vcs或composer)、auth.json域名精确匹配、权限足够(如read:packages)且执行composer clear-cache清除缓存。

Composer 报 401 不是网络不通,也不是包不存在,而是它根本没把认证凭据塞进请求头——相当于你拿钥匙串站在门口,却忘了掏那把对的钥匙。
github-oauth 配置必须带 --auth 标志
很多人执行 composer config -g github-oauth.github.com xxxxxx 后仍 401,核心原因就是漏了 --auth。不加这个标志,Composer 会把 token 存进 config.json,完全不会注入 HTTP 请求头。
- 正确命令:
composer config -g --auth github-oauth.github.com your_token_here - 验证是否生效:
composer config -g github-oauth.github.com应输出掩码后的 token(如****abcd) - 域名必须是
github.com,不是api.github.com或www.github.com,否则匹配失败 - 如果项目根目录有
auth.json,它会覆盖全局配置——先检查是否存在并确认内容
http-basic 凭据要按域名精确写入 auth.json
GitLab、Nexus、自建 Packagist 等服务走的是 HTTP Basic 认证,靠 Authorization: Basic xxx 头,不是 OAuth。Composer 只认 auth.json 里 http-basic 字段下的配置,且域名必须和 repositories.url 完全一致(含端口、子域名)。
- 添加凭证用命令最安全:
composer config -g http-basic.gitlab.example.com username token_value - 若服务跑在非标准端口(如
gitlab.example.com:8443),key 必须写成http-basic.gitlab.example.com:8443 - URL 中不能带用户名(如
https://user@repo.example.com),否则 Composer 会跳过auth.json查找 - 手动编辑
auth.json时,JSON 格式必须合法,一个多余逗号或引号都会让整个认证失效,错误表现仍是模糊的 401
repositories 配置类型错误导致认证被绕过
即使 token 和凭据都对,composer.json 里的 repositories 配置不对,Composer 就压根不会触发认证流程——它可能直接走匿名请求,或者根本没识别出这是个需要认证的源。
- GitHub 私有仓库必须声明
"type": "vcs",否则 Composer 可能忽略github-oauth配置 - 企业私有 Composer 源(如 Nexus、Artifactory)必须用
"type": "composer",不能写成"type": "package"或留空 -
url必须带协议(https://),结尾不能有/;例如"https://packages.internal.company.com"是对的,"https://packages.internal.company.com/"可能触发重定向失败 - 如果
repositories里写了多个源,确保没有同域名但不同协议/端口的冲突项(比如同时存在http://和https://)
缓存和作用域问题常被忽略
新配好 token 或改完 auth.json 后还 401?大概率是旧响应被缓存了,或者权限范围没给够。
- 立刻运行:
composer clear-cache—— 旧的 401 响应可能被本地缓存,新配置不会自动覆盖 - GitHub token 必须勾选
read:packages(最低要求),仅repo权限不够;GitLab token 要含read_api+read_registry - CI 环境中,别依赖全局配置——用
composer config --auth动态写入,或挂载auth.json文件,避免环境残留干扰 - 某些 WAF 或反向代理(如 Nexus 3.21+)会拦截无
User-Agent的请求,可在composer.json的config段加"github-protocols": ["https"]并确保 UA 被透传











