composer不支持客户端证书校验,需通过php.ini配置openssl.local_cert等参数由php底层实现mtls;--cert/--key命令无效,因composer不解析此类参数,仅依赖php的openssl/curl运行时配置。

Composer 本身不支持客户端证书(mTLS)校验,必须靠 PHP 底层 OpenSSL 和 cURL 配合实现;你改 composer.json 或执行 composer config 都无效,得动 php.ini 和证书链。
为什么 Composer 命令加 --cert 或 --key 没用
Composer CLI 不提供客户端证书参数——composer install、composer update 等命令压根不解析 --cert、--key 或类似选项。这些参数只在 curl 命令里生效,而 Composer 的 HTTPS 请求由 PHP 的 stream_context_create() 或 cURL 扩展发起,走的是 PHP 运行时配置,不是命令行参数。
常见错误现象:
- 执行
composer install报错:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca - 抓包看到 Client Hello 后,服务端直接发
Alert (Level: Fatal, Description: Unknown CA) -
curl -v --cert client.crt --key client.key https://private-repo.example.com/packages.json能通,但 Composer 就不行
PHP 层必须启用客户端证书发送
关键不是让 Composer “知道”证书,而是让 PHP 在发起 HTTPS 请求时自动带上客户端证书和私钥。这需要两步硬配置:
- 确保 PHP 编译时启用了
--with-curl且 cURL 版本 ≥ 7.52.0(支持CURLOPT_SSLCERT) - 在 CLI 模式生效的
php.ini中设置以下三项(路径必须为绝对路径):
curl.cainfo = "/path/to/cacert.pem" openssl.cafile = "/path/to/cacert.pem" openssl.local_cert = "/path/to/client.crt" openssl.passphrase = "your-client-key-passphrase-if-any"
注意:openssl.local_cert 必须指向 PEM 格式的证书文件(含完整证书链),不能是 PFX/P12;若私钥有密码,必须通过 openssl.passphrase 提供,否则 PHP 会静默失败。
验证是否加载成功:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
php -r "print_r(openssl_get_cert_locations());"
输出中应看到 local_cert 字段值与你设置的路径一致。
私有源服务端要求的证书链完整性
服务端开启 mTLS 后,不仅校验客户端证书签名,还会校验整个证书链是否可追溯到它信任的 CA。所以你的 client.crt 必须满足:
- 由服务端明确信任的 CA 签发(比如你自建的私有 CA)
- 证书中
Subject的CN或subjectAltName匹配服务端白名单(如CN=dev-team) -
client.crt文件内容需包含:客户端证书 + 中间 CA 证书(如有)+ 不能含私钥 - 服务端配置的 CA 根证书(
ca.crt)必须与签发client.crt的根一致
快速验证链是否有效:
openssl verify -CAfile ca.crt client.crt
输出必须是 client.crt: OK,否则服务端拒绝握手。
容易被忽略的权限与路径陷阱
即使配置全对,也常因两个细节失败:
-
client.crt和client.key(如果私钥未合并进 crt)必须对运行 PHP 的用户可读(Linux/macOS 下常见权限错误:Permission denied) - Windows 用户注意路径分隔符:用正斜杠
/,避免反斜杠转义问题;例如C:/php/ssl/client.crt可行,C:\php\ssl\client.crt可能被 PHP 解析失败 - Docker 容器内务必把证书文件挂载进去,并确认
php.ini中路径指向容器内真实路径(不是宿主机路径) -
openssl.passphrase若含空格或特殊字符,PHP 不支持引号包裹,只能用纯 ASCII 密码
最终效果:Composer 发起的所有 HTTPS 请求(包括 packages.json 获取、dist 下载)都会自动携带客户端证书,服务端完成双向校验后才放行——这不是 Composer 的功能扩展,而是 PHP 运行时 TLS 行为的重定向。










