composer 自定义 http 头必须在 composer.json 的 repositories.vcs.options.http.headers 中配置,仅对 source 模式生效,需配合 --prefer-source 调试,且推荐用 ${var} 环境变量注入 token 保障安全。

composer config 里怎么加自定义 HTTP 头
直接用 composer config 命令没法加请求头——它只管配置文件字段,不处理网络层。真正起作用的是在 repositories 配置里嵌入 options,且仅对 vcs 或 package 类型仓库生效(packagist.org 这类默认源不认这个)。
常见错误是把 http-basic 和自定义 header 混为一谈:前者走 Basic Auth 协议自动加 Authorization,后者得手动塞进 options.http.headers 里。
-
repositories必须是vcs类型(如git),且 URL 是 HTTPS -
options.http.headers是数组,键名必须全小写(比如authorization,不是Authorization) - 值不能含换行或多余空格,否则 cURL 会静默失败
- 如果私有 Git 服务(如 Gitea、GitLab CE)要求 token 放在
X-Gitlab-Token或PRIVATE-TOKEN,就靠这里塞
在 composer.json 里写 headers 的正确格式
别碰全局 auth.json,它只支持 http-basic 和 github-oauth,对自定义 header 完全无效。必须在项目级 composer.json 的 repositories 数组里硬编码:
{
"repositories": [
{
"type": "vcs",
"url": "https://git.example.com/my/private-package.git",
"options": {
"http": {
"headers": {
"private-token": "glpat-abc123xyz",
"user-agent": "composer/2.5.8"
}
}
}
}
]
}
注意:private-token 是 GitLab 私有实例常用头,Gitea 用 authorization + token xxx,Bitbucket Server 用 bitbucket-api-key —— 具体看你的服务文档,大小写和前缀一个都不能错。
为什么 composer install 时 header 没发出去
最常踩的坑是 Composer 根本没走到你配的仓库去拉代码。它优先走 dist(zip 包),而不是 source(git clone),而 options.http.headers 只在 source 模式下生效。
- 确认仓库返回的
composer.json里有"dist"字段:如果有,Composer 会跳过source,header 就失效 - 临时强制走 source:加
--prefer-source调试,看到Cloning ...才算 header 被用了 - 用
COMPOSER_HTTP_PROXY=127.0.0.1:8080 composer install配个本地代理(如 mitmproxy),抓包看实际发出的请求头 - 如果用的是 GitHub/GitLab 的公开域名(如 github.com),Composer 内部有硬编码逻辑绕过自定义 options,必须换自建实例域名
token 放配置里安全吗
不安全。明文写在 composer.json 里等于把凭证提交到代码库,CI/CD 流水线或团队成员都能看到。正确做法是用环境变量注入:
在 composer.json 里写占位符:"private-token": "${GITLAB_TOKEN}",然后运行时设环境变量:GITLAB_TOKEN=glpat-xxx composer install。Composer 会自动替换 ${...},且不会存进锁文件。
但要注意:环境变量方式只在 Composer 2.2+ 支持,旧版本会原样当字符串发出去;另外某些 CI 平台(如 GitHub Actions)需显式用 env: 块暴露变量,不然子进程读不到。
真正难搞的是多环境 token 管理——开发用个人 token,CI 用 project token,测试环境又用另一套。这时候就得靠 config.platform + 自定义脚本预处理,或者干脆放弃 composer.json 硬编码,改用 composer config repositories.xxx.url 动态注册。










