Laragon下Laravel8使用Pusher广播触发cURL error60 SSL证书问题排查
本地Laragon环境Laravel 8对接Pusher私有频道cURL 60错误排查方案
问题根因说明
- 报错核心是CLI队列进程发起对Pusher EU集群API的HTTPS请求时,cURL无法匹配本地存储的可信根证书链,直接触发cURL错误60中断请求。
- 你之前自定义的curl校验规则未生效的原因:Laravel 8适配的Pusher PHP SDK在初始化HTTP客户端时,不会主动解析
options节点下的curl_options配置,只会将options数组作为参数直接传给底层Guzzle客户端,原生的CURLOPT_*常量数组属于无效传参,完全不会被识别。 - 从你输出的
openssl_get_cert_locations()结果能确认两个配置漏洞:一是CLI进程实际默认读取的证书路径是C:\Program Files\Common Files\SSL/cert.pem,和你php.ini里配置的路径不一致;二是php.ini里curl.cainfo和openssl.cafile指向了两个不同的证书文件,只要其中一个文件版本过旧、缺失Pusher域名对应的根证书条目,就会触发校验失败。
分步解决操作
1. 校准CLI进程的实际加载配置
- 在项目根目录打开终端,执行
php --ini,确认队列worker实际加载的php.ini文件路径,不要只修改Web服务绑定的php.ini文件——CLI进程和Web进程通常会读取不同路径的配置文件,之前你只改了Web端的配置,队列worker根本没读到。 - 找到CLI实际加载的php.ini后,修改里面的SSL相关配置,统一指向同一个最新的证书文件,避免路径分散:
extension=openssl curl.cainfo = "C:/laragon/etc/ssl/cacert.pem" openssl.cafile = "C:/laragon/etc/ssl/cacert.pem" - 配置完成后在终端执行
php -r "var_dump(openssl_get_cert_locations());",确认返回的ini_cafile值和你配置的路径完全一致,没有指向其他无效路径。
2. 替换过期的本地CA证书文件
- 用最新版本的CA根证书包,覆盖
C:/laragon/etc/ssl/cacert.pem文件——旧版本Laragon自带的证书包通常是多年前的版本,缺失近年新增的根证书条目,无法匹配Pusher EU集群的服务器证书链。 - 所有证书配置修改完成后,重启所有正在运行的队列worker进程,旧的worker进程会保留启动时的配置缓存,即使改了配置文件也不会自动生效。
3. 修正Pusher配置的正确传参规则
- 不要依赖php.ini的全局配置,直接在
broadcasting.php的Pusher配置里指定Guzzle客户端识别的证书校验规则,这也是SDK支持的优先级最高的配置方式,正确写法如下:'pusher' => [ 'driver' => 'pusher', 'key' => env('PUSHER_APP_KEY'), 'secret' => env('PUSHER_APP_SECRET'), 'app_id' => env('PUSHER_APP_ID'), 'options' => [ 'cluster' => env('PUSHER_APP_CLUSTER'), 'useTLS' => true, // 指定证书校验路径,替代全局php.ini配置 'verify' => "C:/laragon/etc/ssl/cacert.pem", ], ], - *临时排查问题时如果需要跳过证书校验,必须使用Guzzle客户端识别的
verify => false配置,不要写之前那种CURLOPT_*常量数组,SDK完全无法识别这类参数:'options' => [ // ... 原有固定配置 'verify' => false, ],注意:跳过证书校验的配置仅可用于本地临时排查,严禁保留在生产环境配置中,否则会面临HTTPS请求被劫持的安全风险。
4. 私有频道功能验证
- 完成上述配置后,先测试公共频道的推送功能,确认不再出现cURL60报错,再排查私有频道的单独授权流程:
- 检查
routes/channels.php中私有频道的授权规则,确保返回的权限判断结果符合预期 - 确认前端引入的Pusher JS SDK版本和后端SDK的签名算法一致,避免授权签名不匹配导致的连接失败
- 检查
内容的提问来源于stack exchange,提问作者alexmro
相关产品推荐
相关产品推荐

