问题描述
我想使用Guzzle和Silex向https页面发送请求。
I want to use Guzzle and Silex to send request to https pages.
使用http url我有回复:
With http url I have a response :
app->get('/',function() use ($app, $client){
$response = $client->get("http://www.google.fr");
var_dump($response);
});
我的回复:
object(GuzzleHttp\Message\Response)[102]
private 'reasonPhrase' => string 'OK' (length=2)
private 'statusCode' => int 200
private 'effectiveUrl' => string 'http://www.google.fr' (length=20)
private 'headers' (GuzzleHttp\Message\AbstractMessage) =>
array (size=13)
'date' =>
array (size=1)
0 => string 'Wed, 18 Feb 2015 10:57:37 GMT' (length=29)
'expires' =>
但是使用https:
$app->get('/',function() use ($app, $client){
$url = "https://api.zoapp.com/v1/stc/cans/directory/pub/Employees";
$response = $client->get("https://www.facebook.com/");
var_dump($response);
});
我必须犯错:
RequestException in RequestException.php line 51:
和
RingException in CurlFactory.php line 126:
详细信息:
推荐答案
按照指向详细信息的链接,异常消息显示:
Following your link to the details, the exception message says:
查找我找到了
CURLE_SSL_CACERT(60)
对等证书无法使用已知CA进行身份验证证书。
Peer certificate cannot be authenticated with known CA certificates.
所以这很可能是SSL验证/ CA捆绑的问题。通过设置请求选项 false
,guzzle(resp.curl)不会尝试根据证书验证主机,因此错误消失( - 回复)
So it's most likely a problem with the SSL verification/CA bundle. By setting the verify
request option to false
, guzzle (resp. curl) will not try to verify the host against a certificate, hence the error disappears (-- in reply to https://stackoverflow.com/a/28582692/413531)
但是,您不希望这样做;)相反,您应该尝试通过提供有效的CA捆绑包来解决问题。
However, you do not want to do that ;) Instead, you should try to solve the issue by providing a valid CA bundle.
IIRC,在v4 guzzle中提供了默认证书(参见),但在版本5中删除了它,现在尝试发现您的默认系统CA捆绑包。从中,检查这些位置:
IIRC, in v4 guzzle provided a default certificate (see https://github.com/guzzle/guzzle/blob/4.2.3/src/cacert.pem ), but removed that in version 5 and now tries to discover your default system CA bundle. From the docs, those locations are checked:
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)
但是,我发现在创建新的客户端
时,可以更轻松地设置证书。这意味着:
However, I found it easier to set the certificate explicitly when creating a new Client
. That means:
- 下载或更好(因为更新)(参见)
- 在
客户端
实例化中使用此证书的本地路径
- Download https://github.com/guzzle/guzzle/blob/4.2.3/src/cacert.pem or better (because newer) http://curl.haxx.se/ca/cacert.pem (see http://curl.haxx.se/docs/caextract.html)
- Use the local path to this certifcate in the
Client
instantiation
示例(假设您的证书名为 cacert.pem
与脚本位于同一目录中):
Example (assuming you have the certificate named cacert.pem
located in the same directory as the script):
$default = ["verify" => __DIR__ . "/cacert.pem"];
$config = ["defaults" => $default];
$client = new Client($config);
$response = $client->get("https://www.facebook.com");
这篇关于Guzzle和HTTPS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!