我试图用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”
cartalyst/stripe使用的Guzzle,将执行以下操作来查找合适的证书存档来检查服务器证书:
Check if openssl.cafile is set in your php.ini file.
Check if curl.cainfo is set in your php.ini file.
Check if /etc/pki/tls/certs/ca-bundle.crt exists (Red Hat, CentOS, Fedora; provided by the ca-certificates package)
Check if /etc/ssl/certs/ca-certificates.crt exists (Ubuntu, Debian; provided by the ca-certificates package)
Check if /usr/local/share/certs/ca-root-nss.crt exists (FreeBSD; provided by the ca_root_nss package)
Check if /usr/local/etc/openssl/cert.pem (OS X; provided by homebrew)
Check if C:\windows\system32\curl-ca-bundle.crt exists (Windows)
Check if C:\windows\curl-ca-bundle.crt exists (Windows)
你需要通过一个简单的测试来确保前两个设置的值是正确定义的:
echo "openssl.cafile: ", ini_get('openssl.cafile'), "\n";
echo "curl.cainfo: ", ini_get('curl.cainfo'), "\n";
或者,尝试将文件写入#7或#8所指示的位置。
我刚刚在使用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中太难做到了。
希望这为其他人节省了几个小时的调试时间……