Перемещение клиента Curl ssl в 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 и введите его compelete следующим образом:

 $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 задает путь sll curl:

  • Для использования нескольких файлов сертификатов в каталоге Gozzle используется CURLOPT_CAINFO для файла и CURLOPT_CAPATH
  • Путь сертификата по умолчанию – vendor/Http/Resources/cacert.pem .
  • Если вы не используете phar в require_once, вы можете заменить существующий файл сертификата новым сертификатом, потому что он инициализирует SSL при каждом запросе. Это будет работать без изменения кода.
  • Для ssl.certificate_authority сертификации curl ssl используется параметр ssl.certificate_authority . Он поддерживает значения как false, true или file path
  • Вы можете установить путь к файлу, пока инициализация класса, как показано ниже,

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

Для проверки клиента Hzzle Http Doc check – HTTP-клиент Guzzle