auth.json不能提交到git,因其存储明文凭证,一旦入库会导致私有包访问权限泄露;即使配置.gitignore,也易因误删、漏配或git add -f被强制提交。

auth.json 文件为什么不能提交到 Git
因为 auth.json 里存的是明文凭证,一旦进仓库,所有能读代码的人都能拿到私有包访问权。哪怕加了 .gitignore,也常有人误删、漏配或用 git add -f 强制提交。
常见错误现象:
-
git status显示 clean,但auth.json实际在工作区且未被忽略 - CI 流水线里用
composer install成功,本地却失败——因为 CI 用了环境变量,而你本地依赖未配置的auth.json
正确做法:
- 确认
.gitignore包含auth.json(不是./auth.json或**/auth.json这种模糊写法) - 项目初始化后立刻运行
composer config --unset http-basic.repo.example.com清理残留配置 - 用
git check-ignore -v auth.json验证是否真被忽略
COMPOSER_AUTH 环境变量怎么写才不报错
格式错一个字符,composer install 就会静默跳过认证,回退到 public 包源,甚至不报错。它只在解析 JSON 失败时吞掉整个字段。
必须满足三项:
- 单行、无换行、无注释
- 键名严格小写:
http-basic,不是Http-Basic或HTTP_BASIC - URL 域名部分必须和
repositories中完全一致,包括端口(如repo.example.com:8443)
推荐生成方式(避免手拼):
echo '{"http-basic": {"repo.example.com": {"username": "ci", "password": "xxx"}}}' | jq -c
CI 中第一行加校验:
composer config --global --list | grep -q "http-basic" || (echo "MISSING AUTH CONFIG" >&2; exit 1)
为什么全局 auth.json 比项目级更危险
全局 auth.json(位于 ~/.composer/auth.json)会被所有项目共享,只要有一个项目被入侵或误配,整台机器上的私有包访问权限就全暴露了。
典型风险场景:
- 开发机上同时跑多个客户项目,A 项目的
auth.json被 B 项目脚本意外覆盖 - Docker 容器挂载了宿主
~/.composer,导致测试镜像带生产凭证 - PHPStorm 自动把全局配置同步到远程服务器,连带把凭证发到客户云主机
替代方案:
- CI 中一律用
COMPOSER_AUTH,生命周期绑定 job - 本地开发用项目级
auth.json+.gitignore,配合composer config --auth交互式录入 - 禁用全局配置:
composer config --global --unset http-basic.repo.example.com
Bearer Token 和 HTTP Basic 认证怎么选
HTTP Basic(用户名+密码)适合内网固定服务;Bearer Token 更适合 CI token、短期凭证或平台集成(如 GitLab Personal Access Token)。
关键区别:
-
http-basic凭据在请求头中是 Base64 编码,非加密,必须走 HTTPS;bearer是直接透传 token 字符串,同样依赖 HTTPS - GitLab/GitHub 的 Personal Access Token 必须用
bearer方式,填错成http-basic会导致 401 且无明确提示 - Artifactory 的 API Key 属于 bearer 类型,但某些旧版文档误标为 basic,需以实际返回
WWW-Authenticate头为准
验证方式:
curl -I -H "Authorization: Bearer xxx" https://repo.example.com/packages.json
如果返回 200,说明服务端接受 bearer;若返回 401 + WWW-Authenticate: Basic,则必须用 http-basic。
最易被忽略的一点:凭证本身没有有效期,但它的使用上下文有。哪怕你用了最安全的 COMPOSER_AUTH + Bearer Token,如果 Satis 构建时没启用 --sign,或者客户端没开 security.signature-verification,攻击者仍可篡改元数据劫持包版本——凭证只是进门钥匙,签名才是锁住门后的保险柜。











