composer 配置企业私有源需用 auth.json 存凭据并声明 type: "composer" 源,域名须严格匹配、url 带协议不结尾斜杠,ci 中动态生成 auth.json,严禁凭据硬编码或提交 git。

直接结论:Composer 配置 HTTP Basic 认证的企业源,核心是 auth.json 文件 + repositories 声明,且必须确保认证凭据不进 Git、不硬编码在 composer.json 中。
auth.json 文件位置和权限控制
Composer 会自动读取 auth.json,但查找顺序很关键:先查项目根目录(./auth.json),再查 Composer 全局配置目录(~/.composer/auth.json 或 COMPOSER_HOME/auth.json)。企业场景下,推荐用项目级 auth.json,但必须加到 .gitignore —— 否则凭据泄露风险极高。
- 文件内容格式严格:
{"http-basic": {"your-registry.example.com": {"username": "xxx", "password": "yyy"}} - 密码不能是明文 token?可以,但要确认你的内部包管理系统(如 Nexus、Artifactory、Satis)是否接受 token 当作 password 字段值
- Linux/macOS 下建议执行
chmod 600 auth.json,避免被同服务器其他用户读取
repositories 配置必须用 type: "composer"
很多团队误把私有源配成 "type": "package" 或漏掉 "type": "composer",导致 Composer 根本不走 HTTP Basic 流程,而是直接 401 报错或跳过该源。正确写法是让 Composer 明确知道这是个支持 packages.json 的 Composer 类型源。
- 在
composer.json的repositories数组中添加:{ "type": "composer", "url": "https://packages.internal.company.com" } - URL 必须带协议(
https://)、不能以/结尾,否则某些镜像服务(如 Nexus)会 301 重定向失败 - 如果企业源启用了子路径(如
https://nexus.company.com/repository/composer/),就填完整路径,不要省略/repository/composer/
HTTP 401 错误的三个常见原因
运行 composer update 时卡在 Downloading https://... 或直接报 Could not fetch https://...: Failed to authenticate...,大概率不是凭据错,而是下面这些隐蔽问题。
-
auth.json里域名和repositories.url域名不完全一致(比如一个写packages.internal,另一个写https://packages.internal.company.com)——Composer 匹配是精确字符串比对 - 企业源强制 HTTPS 重定向,但 Composer 请求头没带
User-Agent,被 WAF 拦截(Nexus 3.21+ 默认拦截无 UA 的请求);可在config段加"github-protocols": ["https"]并确保网络层允许 UA 透传 - 密码含特殊字符(如
@、/、:)没做 URL 编码 —— 实际不用手动编码,Composer 内部会处理,但如果你手写curl测试,就得用urlencode
CI/CD 环境怎么安全注入凭据
本地开发能放 auth.json,但 CI(如 GitHub Actions、GitLab CI)必须动态生成。硬塞进环境变量再 echo 出来是主流做法,但要注意 JSON 转义和换行。
- GitHub Actions 示例:
- name: Setup auth.json run: | echo '{"http-basic": {"packages.internal.company.com": {"username": "${{ secrets.COMPOSER_USER }}", "password": "${{ secrets.COMPOSER_TOKEN }}"}}}' > auth.json - GitLab CI 中,用
before_script生成,注意双引号需转义或改用单引号包裹整个 JSON 字符串 - 绝对不要在
composer.json里写"http-basic"配置 —— 这会导致凭据进版本库,且 Composer 会忽略它(只认auth.json)
最常被忽略的是域名匹配粒度:哪怕只是多了一个 www. 或少了一个 .com,auth.json 就失效,而错误提示里根本不会告诉你匹配失败,只会笼统报 401。调试时先用 composer config --global --list 确认全局配置加载正常,再用 composer diagnose 检查 auth 文件是否存在且可读。










