php
  • curl
  • ssl
  • guzzle
  • 2014-09-18 3 views 9 likes 
    9

    Ich benutze Guzzle v3.9.2 mit php 5.3 und php 5.5.Moving Curl Client ssl zu Guzzle

    Ich habe die folgenden Arbeits curl Code, der eine SSL-Client-Zertifikat verwendet:

    $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); 
    } 
    

    Ich habe versucht, es zu bewegen, um 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; 
    

    Wenn ich es curl mit betreibe ich eine bekommen 200 Antwort. Als ich Guzzle verwenden erhalte ich eine 403.

    +1

    'cert' Option nur mit Client-Zertifikat arbeiten. Wenn Sie ein privates Zertifikat verwenden, können Sie mit curl keinen privaten Schlüsseldateifehler festlegen. Bitte beziehen Sie sich auf meine Antwort unter –

    Antwort

    13

    wie diese versuchen:

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

    und für die Prüfung dieser Zeile hinzufügen:

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

    oder benutzen Sie diese:

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

    wenn Sie verwenden das selbstgesagte Zertifikat, stellen Sie diese Optionen ein:

    Satz diese Zeile vor Anfrage senden:

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

    Ihre URL überprüfen und geben Sie es wie folgt Compelete:

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

    und Sie können Standardoptionen wie Ihr curl Code hinzu:

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

    Nun, gute Nachrichten und schlecht. Das assertEquals-Zeug zeigt tatsächlich den exakt gleichen Wert. Aber ... irgendwie funktioniert es immer noch nicht. Noch mehr Ideen zum Debuggen? – greggles

    +1

    vor der Sendeanfrage var_dump ($ request-> getCurlOptions()); und siehe created curloptions –

    +0

    Das brachte mich zur Antwort und ich glaube, das ist im Allgemeinen die genaueste Antwort, also nahm ich es an und vergab das Kopfgeld. Mein ultimatives Problem war, dass ich eine 403 über die Tatsache erhielt, dass Verzeichnislisten abgelehnt wurden (der Vorschlag über index.php ließ mich darüber nachdenken). Ich musste die 403-Ausnahme von Guzzle abfangen und den Hauptteil der Anfrage drucken, um zu wissen, dass es sich um einen Fehler "Verzeichnisliste verweigert" anstelle eines Zertifikatfehlers handelte. Vielen Dank! – greggles

    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. 
    

    Dieser Fehler tritt aus drei Gründen auf.

    1. Der korrekte Zertifikatspfad ist nicht angegeben. Daher nicht lesen & übergeben Sie die Zertifikatsinformationen an den Server.
    2. Der Server konnte die Anforderung aufgrund eines ungültigen Zertifikats nicht authentifizieren.
    3. Php curl ist nicht in der Lage, die Zertifikatsdatei wegen Dateibesitzer/Berechtigungsproblem zu lesen.

    Wie Guzzle set ssl curl Pfad:

    • Guzzle CURLOPT_CAINFO für
    • im Verzeichnis für mehrere Zertifikate Datei & CURLOPT_CAPATH verwenden
    • Standardzertifikat Pfad ist vendor/Http/Resources/cacert.pem.
    • Wenn Sie Phar nicht in require_once verwenden, können Sie die vorhandene Zertifikatdatei durch Ihr neues Zertifikat ersetzen, da SSL bei jeder Anforderung initialisiert wird. Dies funktioniert, ohne den Code zu ändern.
    • Guzzle verwendet ssl.certificate_authority Parameter, um die Curl SSL-Zertifizierung festzulegen.Es unterstützt Werte als falsch, wahr oder Dateipfad
    • Sie können den Dateipfad festgelegt, während Klasseninitialisierung als unten-

      $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"; 
      } 
      

    ODER Wenn Sie Zertifikat will bei jeder Anfrage passieren versuchen unten Code

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

    Für Guzzle Http Client Doc Check - The Guzzle HTTP client

    2

    Erstens, weil diese führen zu einer gewissen Verwirrung gibt es zwei Versionen von Guzzle auf Gihub:

    • Guzzle3 (die alte Version, die Sie verwenden)
    • Guzzle (die neue, neu geschriebene Version)

    Hier kommt zwei (getestet in Betrieb) Beispiele eine für jede Version von Guzzle:

    für die aktuellen Versionen von Guzzle (nicht die so genannte ältere Version Guzzle3) es sein sollte:

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

    Stellen Sie sicher, das Client-Zertifikat in PEM Format gespeichert wird. Wenn das Zertifikat durch ein Passwort geschützt ist, müssen Sie es wie folgt angeben:

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

    !! Beachten Sie, dass der obige Code zur Bereitstellung des Passworts im Handbuch beschrieben ist, aber in der aktuellen Version nicht funktioniert hat.

    Für die alte Version Guzzle3 (Sie verwenden)

    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); 
    
    +0

    Danke für den Tipp über PEM. Verwendet curl ein anderes Format als das guzzle für das Zertifikat? Beachten Sie, dass ich diesen Code ein Stück nach dem anderen ausführe und der exakt gleiche Wert von $ cert_file funktioniert gut für Curl und nicht zum Fressen. Nichts über $ url oder $ cert_file ändert sich. – greggles

    +0

    Auch ist Ihr Kommentar über -> get() das Senden der Anfrage nicht konsistent mit den guzzle docs noch meiner Erfahrung. Können Sie auf eine Referenz dazu zeigen? – greggles

    +0

    Nehmen Sie das erste Beispiel auf dieser Seite: https://github.com/guzzle/guzzle/blob/master/docs/clients.rst .. Haben Sie meinen Code ausprobiert? (Ich war zu faul, einen client-basierten Client-Authentifizierungstestserver einzurichten). – hek2mgl

    Verwandte Themen