auth.json权限必须为600,路径须为~/.composer/auth.json(Linux/macOS)或%APPDATA%\Composer\auth.json(Windows),字段名需严格匹配github-oauth或gitlab-token,且须执行composer clear-cache清除旧缓存。

auth.json文件权限不对,600是硬性要求
报错里出现Could not parse authentication file或file_get_contents(/home/alex/.composer/auth.json): failed to open stream: Permission denied,基本就是auth.json权限太高或太低。Composer只认600(即-rw-------),其他值都会拒绝读取。
- 立刻检查:
ls -l ~/.composer/auth.json,输出第一列不是-rw-------就直接失败 - 修复命令:
chmod 600 ~/.composer/auth.json(别加-R,只改这个文件) - Windows用户注意:
%APPDATA%\Composer\auth.json也要确保文件属性里“安全”标签下只有当前用户有读取权限,禁用“继承权限” - 编辑器保存时可能带BOM头,导致JSON解析失败——用
file -i ~/.composer/auth.json确认charset=utf-8,不是utf-8-with-bom
auth.json路径错位,Composer根本没找到它
报错不提路径,但composer config --global --list里完全看不到http-basic或github-oauth字段,说明Composer压根没加载到auth.json。
- Linux/macOS必须放在
~/.composer/auth.json,不能放项目根目录下(除非composer.json里显式声明"config": {"auth-file": "auth.json"}) - 检查
COMPOSER_HOME是否被覆盖:echo $COMPOSER_HOME,如果输出/root/.composer或/var/www/.composer,说明环境变量污染了,要重置 - 临时验证:运行
COMPOSER_HOME=$HOME/.composer composer config --global http-basic.example.com test pass,看是否能写入 - Git提交过
auth.json?赶紧git rm --cached ~/.composer/auth.json并加进.gitignore,否则凭据会泄露
GitHub/GitLab token填错字段名,401伪装成文件读取失败
明明auth.json权限和路径都对,但报错还是Invalid credentials,其实是字段名写错了——Composer把认证失败统一归为“无法读取凭据”,不区分是文件问题还是token无效。
- GitHub必须用
github-oauth字段,key是github.com(不是api.github.com或raw.githubusercontent.com) - GitLab用
gitlab-token字段,key是完整域名+端口,如gitlab.example.com:8080(少端口就匹配不上) - classic PAT必须勾选
read:packages(GitHub)或apiscope(GitLab),fine-grained token需额外开启packages:read - 快速验证token:
curl -H "Authorization: Bearer ghp_xxx" https://api.github.com/user/packages | head -n1,返回{才算有效
缓存锁住旧配置,改完auth.json也不生效
删了旧token、改了auth.json、甚至重装Composer,还是报错——缓存里存着旧的认证元数据,Composer优先读缓存而非文件。
- 强制清缓存:
composer clear-cache(不是composer cache-clear,后者是旧版命令) - 验证是否清干净:
ls -la $(composer config --global cache-dir),确认里面没有repo/https---github.com这类残留目录 - 某些镜像源(如私有Packagist)会在首次请求时把认证信息缓存进
cache/repo/子目录,不清缓存永远走老路径 - CI/CD中建议加
--no-cache参数绕过缓存,比如composer install --no-cache --no-interaction
auth.json就形同虚设。最常被忽略的是缓存残留和GitHub域名写错,这两处不会报路径错误,却让所有修改看起来“没用”。


















