敏感认证信息绝不能硬编码在composer.json中,否则凭据将明文进入Git历史难以清除;必须通过全局auth.json(配合.gitignore)或COMPOSER_AUTH环境变量管理,且CI中须用 secrets 注入凭证。

敏感认证信息绝不能出现在 composer.json 或命令行中,必须剥离到外部载体,并确保不被 Git 跟踪——否则等于把私有包仓库的登录凭证明文上传。
为什么不能把 token 写进 composer.json 的 repositories 字段
常见错误是这样写:
"repositories": [
{
"type": "composer",
"url": "https://token:abc123@packagist.internal"
}
]
这会导致 token 进入 Git 历史,即使后续删掉也难以彻底清除。Git 不会自动加密或忽略这类字符串,且 composer.json 本身是公开可读的配置文件。
- 所有私有源 URL 中的认证部分(
user:pass@或token@)都属于硬编码密钥,禁止出现 - Composer 从不校验 URL 是否含敏感内容,它只负责解析和请求
- CI 日志一旦打印出该 URL,密钥就已泄露
正确做法:用全局 auth.json + .gitignore 双保险
Composer 会自动查找并加载 ~/.composer/auth.json(Linux/macOS)或 %APPDATA%\Composer\auth.json(Windows),你只需确保它存在、权限正确、且不在 Git 索引里。
- 运行
composer config --global --auth http-basic.packagist.internal username password,它会自动创建文件、设权限为600 - 手动检查文件路径:
composer config --global --list | grep config-home - 确认
auth.json没被 Git 跟踪:git check-ignore -v auth.json,若无输出,说明未忽略,需补上auth.json到项目根目录的.gitignore - 如果它已被 commit 过,执行
git rm --cached auth.json(仅从索引移除,保留本地)
CI 环境必须用环境变量注入,而非写文件
GitHub Actions、GitLab CI 等无交互环境无法弹出密码提示,也不能依赖本地 auth.json 文件——那文件根本不存在于 runner 上。
- GitHub Actions 推荐写法:
composer config --global --auth http-basic.packagist.internal ${{ secrets.PACKAGIST_USER }} ${{ secrets.PACKAGIST_TOKEN }} - GitLab CI 写法:
composer config --global --auth http-basic.packagist.internal "$PACKAGIST_USER" "$PACKAGIST_TOKEN" - 避免用
echo '{...}' > ~/.composer/auth.json:JSON 格式易错、权限可能为644、内容残留风险高 - 注意:
COMPOSER_AUTH环境变量方式对http-basic类型支持有限,某些自建仓库(如 Artifactory)需查文档确认是否兼容
store-auths false 并不能真正“隐藏”,只是禁用自动保存
运行 composer config --global store-auths false 后,Composer 遇到私有源会暂停等待人工输入,但不会把凭据存进 auth.json——这在自动化流程中等于直接失败。
- 这个设置只影响“是否自动写入”,不影响“是否读取已有
auth.json” - 它不阻止你手动创建或 CI 动态写入
auth.json - 如果你已用
--global --auth配过,store-auths false完全无效;它只管下次交互式输入要不要存 - 真正关键的不是关开关,而是确保凭据来源可信、路径受控、生命周期清晰
最难防的不是配置不会写,而是写了没验证是否真被忽略,或者多人协作时有人绕过流程直接 echo 进 composer.json —— 每次 git add 前,值得花三秒跑一次 git diff --no-index /dev/null composer.json | grep -i 'token\|password\|@'。


















