auth.json必须放在项目根目录或$composer_home目录(如~/.composer/auth.json),按优先级顺序查找且找到即停;权限需设为600(linux/macos),域名须与仓库url主机名完全匹配,字段名须正确对应http-basic或github-oauth等认证类型。

Composer拉取包时提示输入密码,90%不是网络或权限问题,而是凭证没被正确加载——auth.json放错位置、权限不对、域名不匹配,或者根本没生成。
auth.json放哪才生效?路径和权限必须严格
Composer只在两个地方找auth.json:项目根目录(优先),或COMPOSER_HOME目录(通常是~/.composer/auth.json)。它不会递归查找,也不会读vendor/或子目录下的同名文件。
- 项目级推荐:把
auth.json放在和composer.json同一级,内容为{"http-basic": {"your-mirror.example.com": {"username": "api", "password": "ghp_abc123"}}} - 权限必须是
600(Linux/macOS):chmod 600 auth.json,否则 Composer 会静默忽略该文件 - 别用
echo '{...}' > auth.json直接写——容易带BOM或换行符,建议用vim或jq生成
http-basic vs github-oauth:字段名写错就白配
不同认证方式对应不同auth.json字段名,拼错一个字母就完全不生效。
- 私有 Packagist / Artifactory / Nexus 等基础认证服务 → 用
http-basic字段 - GitHub/GitLab 私有包(含 GitHub Packages)→ 用
github-oauth字段,键是域名,值是 token:{"github-oauth": {"github.com": "ghp_abc123"}} - Bearer Token 场景(如某些私有镜像)→ 不是
http-basic,也不是github-oauth,需确认服务文档是否要求bearer字段(少数平台支持)
CI/CD里卡住不动?--no-interaction不是万能解药
在 Docker 构建、GitHub Actions 或 Jenkins 中运行composer install卡住,大概率是 stdin 不可交互 + auth.json缺失。加--no-interaction只是让报错更快,但不能替代凭证配置。
- 先验证环境是否 TTY:
php -r "var_dump(stream_isatty(STDIN));"返回false就是非交互环境 -
--no-interaction必须配合已存在的auth.json,否则直接失败退出,错误是401 Unauthorized - CI 中推荐用
COMPOSER_AUTH环境变量注入:export COMPOSER_AUTH='{"http-basic": {...}}',避免文件挂载权限问题
curl能通但composer不行?检查 Realm 和 Host 匹配
用curl -v -u api:token https://your-mirror.example.com/packages.json返回 200,不代表 Composer 就能过——它发的Authorization头可能被服务端拒绝。
- Artifactory 默认 Realm 是
Artifactory Realm,Nexus 是Nexus Repository Manager;如果镜像配置了自定义 Realm,Composer 必须匹配才能通过 - 域名必须完全一致:如果仓库 URL 是
https://pkg.internal.company.com,auth.json里的 key 就得是"pkg.internal.company.com",不能写成"internal.company.com"或带www. - 某些反向代理(如 Nginx)会 strip 掉
Authorization头,需显式配置proxy_pass_request_headers on;
最常被忽略的一点:即使auth.json配置正确、curl测试成功、composer install也跑完了,私有包仍可能不加载——因为vendor/autoload.php找不到类,这和鉴权无关,是私有包自身composer.json里autoload字段漏写了。鉴权只是下载门槛,自动加载是另一层事。











