将Curl客户端ssl移动到Guzzle

时间:2014-09-18 23:41:10

标签: php curl ssl guzzle

我使用Guzzle v3.9.2同时使用php 5.3和php 5.5。

我有以下使用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。

3 个答案:

答案 0 :(得分:14)

尝试这样:

 $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';

您可以添加像卷曲代码一样的默认选项:

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

答案 1 :(得分:2)

首先,因为这导致了一些混乱,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);

答案 2 :(得分:1)

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无法读取证书文件。
  4. 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客户端文档检查 - The Guzzle HTTP client