laravel 8 中 curl ssl 校验需同时设 curlopt_ssl_verifypeer => true 和 curlopt_ssl_verifyhost => 2,并指定绝对路径的 ca 证书(如 cacert.pem),缺一不可;http facade 用 withoptions(['verify' => path]) 实现等效配置。

在 Laravel 8 中,cURL 的 SSL 校验不是通过 Laravel 框架本身配置的,而是由底层 PHP cURL 扩展控制。Laravel 的 Http Facade 或原生 curl_init() 调用都需显式设置对应选项,CURLOPT_SSL_VERIFYPEER 必须配合 CURLOPT_SSL_VERIFYHOST 和证书路径才真正生效。
必须同时开启两个校验开关
只设 CURLOPT_SSL_VERIFYPEER => true 是不够的,容易误以为已启用安全校验:
-
CURLOPT_SSL_VERIFYPEER => true:验证证书是否由可信 CA 签发(依赖 CA 证书文件) -
CURLOPT_SSL_VERIFYHOST => 2:严格校验域名是否匹配证书中的 SAN 或 CN(值为 2,不能是 1) - 二者缺一不可,否则可能跳过关键验证,比如用 example.com 的证书访问 api.example.com 仍会通过
必须指定可信 CA 证书路径
PHP 不读系统证书库,CURLOPT_SSL_VERIFYPEER => true 会因找不到根证书而报错 unable to get local issuer certificate:
- 推荐使用 Mozilla 官方维护的
cacert.pem(从 https://curl.se/ca/cacert.pem 下载) - 存入项目目录如
storage/certs/cacert.pem,调用时用绝对路径:curl_setopt($ch, CURLOPT_CAINFO, storage_path('certs/cacert.pem')); - 避免相对路径或未用
realpath()处理,防止工作目录变化导致路径失效
用 Http Facade 时如何控制
Laravel 8 的 Http:: 默认不暴露 cURL 底层参数,但可通过 withOptions() 注入:
Http::withOptions(['verify' => storage_path('certs/cacert.pem')])->get('https://api.example.com');- 该
verify选项等价于同时启用CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST - 若设为
false,则完全跳过校验(仅限调试,禁止用于生产)
自签名或私有 CA 场景处理
对接内部服务时,不能关闭校验,而应把自签名证书或企业根证书加入信任链:
- 将
server.crt或internal-ca.crt单独作为CURLOPT_CAINFO值传入 - 或合并进
cacert.pem文件(追加内容即可) - 切勿用
CURLOPT_SSL_VERIFYPEER => false“快速修复”,这等于放弃 TLS 安全保障











