我试图用Stripe发送一个API请求,但得到错误消息:
cURL错误60:SSL证书问题:无法获得本地颁发者证书
这是我正在运行的代码:
public function chargeStripe()
{
$stripe = new Stripe;
$stripe = Stripe::make(env('STRIPE_PUBLIC_KEY'));
$charge = $stripe->charges()->create([
'amount' => 2900,
'customer' => Input::get('stripeEmail'),
'currency' => 'EUR',
]);
return Redirect::route('step1');
}
我在谷歌上搜索了很多,很多人建议我下载这个文件:cacert。Pem,把它放在某处,并在我的php.ini中引用它。这是我的php.ini中的部分:
curl.cainfo = "C:\Windows\cacert.pem"
然而,即使在重新启动服务器几次并更改路径之后,我仍然得到相同的错误消息。
我在Apache中启用了ssl_module,在我的php.ini中启用了php_curl。
我还尝试了这个修复:如何修复PHP CURL错误60 SSL
这表明我将这些行添加到我的cURL选项:
curl_setopt($process, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
curl_setopt($process, CURLOPT_SSL_VERIFYPEER, true);
我在哪里添加选项到我的cURL?显然不是通过命令行,因为我的CLI没有找到命令“curl_setopt”
有一天,当Guzzle(5)脚本试图通过SSL连接到主机时,我突然出现了这个问题。当然,我可以在Guzzle/Curl中禁用验证选项,但这显然不是正确的方法。
我在类似的线程中尝试了这里列出的所有内容,然后最终使用openssl进入终端,对我试图连接的域进行测试:
openssl s_client -connect example.com:443
... 收到的前几行是:
CONNECTED(00000003)
depth=0 CN = example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = example.com
verify error:num=21:unable to verify the first certificate
verify return:1
... 当尝试其他目的地(如:google.com等)时,一切都很好
这促使我联系了我一直试图连接的域名,事实上,他们在他们的一端有一个问题,已经悄然出现。问题解决了,我的剧本又开始运作了。
所以…如果您非常着急,请尝试openssl,并查看您试图连接的位置的响应是否有任何变化。也许有时候这个问题并不那么“地方性”。
我刚刚在使用guzzlehttp/guzzle composer包的Laravel 4 php框架中遇到了同样的问题。出于某种原因,mailgun的SSL证书突然停止验证,我收到了同样的“错误60”消息。
如果像我一样,您在一个共享主机上,没有访问php.ini的权限,那么其他解决方案是不可能的。在任何情况下,Guzzle有这样的客户端初始化代码,很可能会使php.ini效果无效:
// vendor/guzzlehttp/guzzle/src/Client.php
$settings = [
'allow_redirects' => true,
'exceptions' => true,
'decode_content' => true,
'verify' => __DIR__ . '/cacert.pem'
];
在这里,Guzzle强制使用自己的内部cacert。pem文件,这个文件现在可能已经过时了,而不是使用cURL环境提供的文件。修改这一行(至少在Linux上)配置Guzzle使用cURL的默认SSL验证逻辑,并解决了我的问题:
由于vendor中的文件并不意味着被篡改,一个更好的解决方案是在使用时配置Guzzle客户端,但这在Laravel 4中太难做到了。
希望这为其他人节省了几个小时的调试时间……