Composer报401实为auth.json中token被revoke或权限回收,非镜像源过期;应删所有auth.json、清缓存、用composer config --global --auth重配,确保域名纯host、权限600、属主正确。

Composer报401但镜像源没变,其实是auth.json里token被revoke了
不是镜像源“过期”,是里面配的token已被手动删掉或权限回收。GitHub/GitLab 控制台里删过 token、公司管理员撤回过 access scope、甚至自己换过密码触发 token 失效,都会让 auth.json 里的值变成无效凭据。Composer 不会主动告诉你“这个 token 已被 revoke”,只会统一报 401 Unauthorized 或 Could not authenticate。
验证方式很简单:直接 curl 模拟请求——比如 GitHub Packages 地址,带上你 auth.json 里的 token:
curl -H "Authorization: Bearer <your-token>" https://npm.pkg.github.com/-/user/orgs
如果返回 401 或 {"message":"Bad credentials"},基本就是 token 废了。别查 DNS、别试代理,先确认凭据本身是否还活着。
auth.json域名写错导致认证被跳过,常见于https://开头或带/api/v4路径
Composer 对 http-basic 域名字段要求严格:必须是纯 host,不能带协议、端口或路径。填成 https://gitlab.example.com 或 gitlab.example.com/api/v4 都会导致整段配置被忽略,静默 fallback 到无认证状态。
- 正确写法:
gitlab.example.com(无协议、无路径) - GitHub Packages 正确域名:
github.com(不是npm.pkg.github.com,那是 registry URL,不是 auth 域名) - 私有 Packagist 正确写法:
packagist.company.com(和repositories里定义的url主机名完全一致)
用 composer config --global --list | grep http-basic 查看当前生效的配置项,注意输出里 key 的格式是否干净。
删掉所有auth.json再重配,别试图修旧文件
多个 auth.json 共存时(项目根目录 + ~/.composer/auth.json + CI 环境挂载残留),Composer 只读第一个,其余全被忽略。旧文件里可能混着过期 token、错误域名、甚至 JSON 语法错误(比如多逗号、单引号),手动改容易漏掉细节。
最稳妥的做法是清空重来:
- 删项目级:
rm -f auth.json - 删全局级:
rm -f $(composer config --global home)/auth.json - 清缓存:
composer clear-cache - 重配(以 GitHub 为例):
composer config --global --auth github-oauth.github.com <new-token>
这条命令会自动写入合法 JSON、设好权限(600)、跳过 shell 历史记录 token —— 比手写安全,也比 composer config --global github-oauth.github.com 少一层输错风险。
权限不对时chown比chmod管用,尤其/root/.composer/auth.json
如果 auth.json 所在目录或文件属主是 root(比如曾用 sudo composer config),哪怕 chmod 777 也没用。Linux 内核不允许非属主进程往非属主文件写内容,Composer 直接卡在 file_put_contents(): Failed to open stream: Permission denied。
查归属:ls -ld $(composer config --global home)/auth.json,第三列不是当前用户名就说明问题。
修复命令只有一条:
sudo chown -R $(whoami):$(whoami) $(composer config --global home)
注意是 -R,因为 ~/.composer 下可能还有插件目录也要一并归还。别碰 chmod,它解决不了所有权问题。
真正麻烦的不是 token 过期,而是旧凭据残留+路径错位+权限错位三者叠加。每次出问题,先删文件、再查归属、最后重配,比对着日志猜原因快得多。


















