PHP CURL & HTTPS

70

Ich habe diese Funktion gefunden, die einen fantastischen Job macht (IMHO): http://nadeausoftware.com/articles/2007/06/php_tip_how_get_web_page_using_curl

/**
 * Get a web file (HTML, XHTML, XML, image, etc.) from a URL.  Return an
 * array containing the HTTP server response header fields and content.
 */
function get_web_page( $url )
{
    $options = array(
        CURLOPT_RETURNTRANSFER => true,     // return web page
        CURLOPT_HEADER         => false,    // don't return headers
        CURLOPT_FOLLOWLOCATION => true,     // follow redirects
        CURLOPT_ENCODING       => "",       // handle all encodings
        CURLOPT_USERAGENT      => "spider", // who am i
        CURLOPT_AUTOREFERER    => true,     // set referer on redirect
        CURLOPT_CONNECTTIMEOUT => 120,      // timeout on connect
        CURLOPT_TIMEOUT        => 120,      // timeout on response
        CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects
    );

    $ch      = curl_init( $url );
    curl_setopt_array( $ch, $options );
    $content = curl_exec( $ch );
    $err     = curl_errno( $ch );
    $errmsg  = curl_error( $ch );
    $header  = curl_getinfo( $ch );
    curl_close( $ch );

    $header['errno']   = $err;
    $header['errmsg']  = $errmsg;
    $header['content'] = $content;
    return $header;
}

Das einzige Problem, das ich habe, ist, dass es für https: // nicht funktioniert. Anny Ideen, was ich tun muss, damit dies für https funktioniert? Vielen Dank!

StackOverflowNewbie
quelle
4
Definieren Sie bitte "funktioniert nicht".
Präsident James K. Polk
3
Überprüfen Sie standardmäßig, ob das SSL-Zertifikat gültig ist. Möglicherweise möchten Sie dieses Verhalten deaktivieren, wenn Sie das betreffende Zertifikat selbst signiert haben
RageZ
@RegeZ - wie mache ich deinen Vorschlag?
StackOverflowNewbie
verwandt: stackoverflow.com/questions/316099/…
Dieser Brasilianer
Die als richtig gekennzeichnete Antwort sollte nicht die richtige sein.
Gavin Palmer

Antworten:

115

Schnelle Lösung, fügen Sie dies in Ihren Optionen hinzu:

curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false)

Jetzt haben Sie keine Ahnung, zu welchem ​​Host Sie tatsächlich eine Verbindung herstellen, da cURL das Zertifikat in keiner Weise überprüft. Ich hoffe, Sie genießen Man-in-the-Middle-Angriffe !

Oder fügen Sie es einfach Ihrer aktuellen Funktion hinzu:

/**
 * Get a web file (HTML, XHTML, XML, image, etc.) from a URL.  Return an
 * array containing the HTTP server response header fields and content.
 */
function get_web_page( $url )
{
    $options = array(
        CURLOPT_RETURNTRANSFER => true,     // return web page
        CURLOPT_HEADER         => false,    // don't return headers
        CURLOPT_FOLLOWLOCATION => true,     // follow redirects
        CURLOPT_ENCODING       => "",       // handle all encodings
        CURLOPT_USERAGENT      => "spider", // who am i
        CURLOPT_AUTOREFERER    => true,     // set referer on redirect
        CURLOPT_CONNECTTIMEOUT => 120,      // timeout on connect
        CURLOPT_TIMEOUT        => 120,      // timeout on response
        CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects
        CURLOPT_SSL_VERIFYPEER => false     // Disabled SSL Cert checks
    );

    $ch      = curl_init( $url );
    curl_setopt_array( $ch, $options );
    $content = curl_exec( $ch );
    $err     = curl_errno( $ch );
    $errmsg  = curl_error( $ch );
    $header  = curl_getinfo( $ch );
    curl_close( $ch );

    $header['errno']   = $err;
    $header['errmsg']  = $errmsg;
    $header['content'] = $content;
    return $header;
}
SystemX17
quelle
2
Weitere Informationen hierzu finden Sie hier: unitstep.net/blog/2009/05/05/…
SystemX17
das ist ok - ich bin erst seit gestern neu hier. Vielen Dank, dass Sie diesen Code für die fragende Person verbessert haben - ur awesome.
SystemX17
27
Wenn Sie CURLOPT_SSL_VERIFYPEER auf false setzen, können Man-in-the-Middle-Angriffe ausgeführt werden. rmckay bei webaware dot com dot au warnt davor auf nl3.php.net/manual/en/function.curl-setopt.php und bietet eine alternative Lösung, die funktioniert: Laden Sie ein CA- Stammzertifikat- Bundle von der Curl-Website herunter und speichern Sie es weiter Ihr Server. Scrollen Sie auf der angegebenen Website zu den Benutzerkommentaren.
Paul Gobée
36

Ich habe versucht, CURL zu verwenden, um einige https-API-Aufrufe mit PHP durchzuführen, und bin auf dieses Problem gestoßen. Ich bemerkte eine Empfehlung auf der PHP-Site, die mich zum Laufen brachte: http://php.net/manual/en/function.curl-setopt.php#110457

Bitte hören Sie auf, CURLOPT_SSL_VERIFYPEER auf false oder 0 zu setzen. Wenn Ihre PHP-Installation kein aktuelles CA-Stammzertifikat-Bundle enthält, laden Sie das auf der Curl-Website herunter und speichern Sie es auf Ihrem Server:

http://curl.haxx.se/docs/caextract.html

Legen Sie dann in Ihrer Datei php.ini einen Pfad dazu fest, z. B. unter Windows:

curl.cainfo = c: \ php \ cacert.pem

Durch Deaktivieren von CURLOPT_SSL_VERIFYPEER können Man-in-the-Middle-Angriffe (MITM) ausgeführt werden, die Sie nicht möchten!

Gavin Palmer
quelle
3
Ich habe das getan, aber jetzt bekomme ich nur35 error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
OZZIE
5

Eine andere Option wie die Antwort von Gavin Palmer ist die Verwendung der .pemDatei, jedoch mit einer Curl-Option

  1. Laden Sie die zuletzt aktualisierte .pemDatei von https://curl.haxx.se/docs/caextract.html herunter und speichern Sie sie irgendwo auf Ihrem Server (außerhalb des öffentlichen Ordners).

  2. Stellen Sie die Option in Ihrem Code anstelle der php.iniDatei ein.

In deinem Code

curl_setopt($ch, CURLOPT_CAINFO, $_SERVER['DOCUMENT_ROOT'] .  "/../cacert-2017-09-20.pem");

HINWEIS: Das Einstellen des Cainfo php.iniwie bei @Gavin Palmer ist besser als das Einstellen in Ihrem Code wie bei mir, da bei jedem Aufruf der Funktion eine Festplatten-E / A gespeichert wird. Ich mache es einfach so, falls Sie es testen möchten die cainfo-Datei im laufenden Betrieb, anstatt sie php.inibeim Testen Ihrer Funktion zu ändern .

Buchhalter م
quelle
1

Ein wichtiger Hinweis: Die oben erwähnte Lösung funktioniert nicht auf dem lokalen Host. Sie müssen Ihren Code auf den Server hochladen und dann funktioniert es. Ich habe keinen Fehler erhalten, als eine schlechte Anfrage. Das Problem war, dass ich localhost (test.dev, myproject.git) verwendet habe. Beide oben genannten Lösungen funktionieren. Es wird die Lösung empfohlen, die das SSL-Zertifikat verwendet.

  1. Gehen Sie zu https://curl.haxx.se/docs/caextract.html und laden Sie die neueste Datei cacert.pem herunter. Der Speicher befindet sich irgendwo (nicht im öffentlichen Ordner - funktioniert aber trotzdem)

  2. Verwenden Sie diesen Code

". $ result; // echo"
Path: ". $ _ SERVER ['DOCUMENT_ROOT']." /ssl/cacert.pem "; // Dies dient nur zur Fehlerbehebung?>
  1. Laden Sie den Code auf den Live-Server hoch und testen Sie ihn.
Hammad Khan
quelle