繁体   English   中英

将Curl客户端ssl移动到Guzzle

[英]Moving Curl client ssl to Guzzle

我正在使用Guzzle v3.9.2与php 5.3和php 5.5。

我有以下工作curl代码使用ssl客户端证书:

$url = "https://example.com/";
$cert_file = '/path/to/certificate.pem';

$ch = curl_init();
$options = array(
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_URL => $url ,
  CURLOPT_SSLCERT => $cert_file ,
);

curl_setopt_array($ch , $options);
$output = curl_exec($ch);

if (!$output) {
  echo "Curl Error : " . curl_error($ch);
}
else {
  echo htmlentities($output);
}

我试图把它移到Guzzle:

require '/var/www/vendor/autoload.php';
use Guzzle\Http\Client;
$client = new Client();
$request = $client->get($url, array('cert' => $cert_file));
$response = $client->send($request);
echo $response . PHP_EOL;
print 'HI' . PHP_EOL;

当我使用curl运行它时,我得到200响应。 当我使用Guzzle时,我得到403。

试试这样:

 $client = new Client();
 $response = $client->get($url, array(), array('cert' => $cert_file));

并检查添加此行:

 $this->assertEquals($cert_file, $request->getCurlOptions()->get(CURLOPT_SSLCERT));

或使用此:

 $client = new Client();
 $request = $client->createRequest('GET', $url);
 $request->getCurlOptions()->set(CURLOPT_SSLCERT, $cert_file);
 $response = $client->send($request);

如果您使用自签名证书设置此选项:

$request->getCurlOptions()->set(CURLOPT_SSL_VERIFYHOST, false);
$request->getCurlOptions()->set(CURLOPT_SSL_VERIFYPEER, false);

在发送请求之前设置此行:

$request = $client->get( .... )
.
.
.
$request->setResponse(new Response(200), true);
$request->send();

检查你的网址并输入它,如下所示:

$url = 'https://example.com/index.php';

并且您可以添加像curl代码一样的默认选项:

$request->getCurlOptions()->set(CURLOPT_RETURNTRANSFER , true);
$request->getCurlOptions()->set(CURLOPT_FOLLOWLOCATION , true);

首先,因为这导致了一些混乱,Gihub上有两个版本的Guzzle:

  • Guzzle3 (旧版本,你正在使用)
  • Guzzle (新版,改写版)

这里有两个(经过测试的工作)示例,每个版本的Guzzle一个:

对于Guzzle的最新版本(不是所谓的旧版本Guzzle3),它应该是:

use GuzzleHttp\Client;

$client = new Client();
$response = $client->get($url, array('cert' => $cert_file));

var_dump($response);

确保客户端证书以PEM格式存储。 如果证书受密码保护,您需要像下面这样指定:

$response = $client->get($url, 
    array('cert' => array($cert_file, 'password' => '****'));

请注意,上面提供密码的代码在手册中有描述,但在最近的版本中没有用。

对于旧版本Guzzle3(您正在使用)

use Guzzle\Http\Client;

// Create a client and provide a base URL
$client = new Client();

$request = $client->get($url, array(), array(
    'cert' => $cert_file
));

// You must send a request in order for the transfer to occur
$response = $request->send();

var_dump($response);
If you are using private key then you have to use ssl_key option it will not 
work with cert.You can use **cert** options only with client certificate.

出现此错误的原因有三个。

  1. 未提供正确的证书路径。 因此无法读取证书信息并将其传递给服务器。
  2. 由于证书无效,服务器无法验证请求。
  3. 由于文件所有者/权限问题,Php curl无法读取证书文件。

Guzzle如何设置ssl卷曲路径:

  • 对于目录中的多个证书,Guzzle使用CURLOPT_CAINFO作为文件和CURLOPT_CAPATH
  • 默认证书路径是vendor/Http/Resources/cacert.pem
  • 如果您不在require_once中使用phar,则可以使用新证书替换现有证书文件,因为它会在每次请求时初始化SSL。 这将在不更改代码的情况下工作。
  • Guzzle使用ssl.certificate_authority参数来设置curl ssl认证。 它支持false,true或文件路径的值
  • 您可以在类初始化时设置文件路径,如下所示 -

     $cert_file = '/var/www/stack/25924147/cert/example.pem'; #Use absolute path as relative path will not work $client = new Client(); $client->setDefaultOption('verify',true); #pass it for self-signed certificate $client->setSslVerification($cert_file,true,2); #Last Verify Option states default value is 2. When the verify value is 0, the connection succeeds regardless of the names in the certificate. Use that ability with caution!. When the verify value is 1, curl_easy_setopt will return an error try{ $request = $client->get($url); $options = $request->getCurlOptions(); #used to check curl options is set properly. var_dump($options); $response = $client->send($request); echo $response . PHP_EOL; print 'HI' . PHP_EOL; }catch( Guzzle\\Http\\Exception\\CurlException $e){ print_r($e->getResponse()); echo "\\n Curl Error \\n"; }catch(Guzzle\\Http\\Exception\\ClientErrorResponseException $e){ print_r($e->getResponse()); echo "\\n Response Error \\n"; }catch( Guzzle\\Http\\Exception\\RequestException $e){ print_r($e->getResponse()); echo "\\n REquest Error \\n"; } 

或者如果您想在每个请求上传递证书,请尝试以下代码

   $cert_file = '/var/www/stack/25924147/cert/example.pem'; #Use absolute path as relative path will not work
   $client = new Client();
   $request = $client->get('https://www.example.com', array(), array(

      'ssl_key' => array('/etc/pki/private_key.pem')

  )


With Passoword - 
 $request = $client->get('https://www.example.com', array(), array(

     'ssl_key' => array('/etc/pki/private_key.pem', 's3cr3tp455w0rd')

 )

对于Guzzle Http客户端Doc检查 - Guzzle HTTP客户端

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM