web-dev-qa-db-fra.com

Impossible de se connecter au site HTTPS à l'aide de cURL. Renvoie le contenu de la longueur à la place. Que puis-je faire?

J'ai un site qui se connecte via cURL (dernière version) à une passerelle sécurisée pour le paiement.

Le problème est que cURL renvoie toujours un contenu de longueur 0. Je ne reçois que des en-têtes. Et seulement quand je règle cURL pour retourner les en-têtes. J'ai les drapeaux suivants en place.

curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_URL, $gatewayURI);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_POST, 1);

L'en-tête renvoyé est

HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Date: Tue, 25 Nov 2008 01:08:34 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Content-Length: 0
Content-Type: text/html
Set-Cookie: ASPSESSIONIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/
Cache-control: private

J'ai également essayé de cURL'ing différents sites et ils renvoient du contenu très bien. Je pense que le problème pourrait avoir quelque chose à voir avec la connexion https.

J'ai parlé avec l'entreprise et ils sont inutiles.

Quelqu'un d'autre a-t-il rencontré cette erreur et a-t-il connaissance d'un problème? Devrais-je laisser tomber CURL et essayer d'utiliser fsockopen()?

Je vous remercie. :)

61
alex

Vous devriez également essayer de vérifier les messages d'erreur dans curl_error (). Vous devrez peut-être faire cela une fois après chaque fonction curl_ *.

http://www.php.net/curl_error

33
too much php

J'ai eu le même problème aujourd'hui… .. Curl est livré avec un fichier obsolète d'authentification des certificats HTTPS.

obtenir le nouveau de:

http://curl.haxx.se/ca/cacert.pem

enregistrez-le dans un répertoire de votre site 

et ajouter 

curl_setopt ($curl_ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem"); 

A chaque demande :-)

IGNOREZ tous les commentaires stupides sur la désactivation de CURLOPT_VERIFYPEER et CURLOPT_VERIFYHOST !! Cela laisse votre code vulnérable aux attaques de l'homme au milieu!

Décembre 2016 edit:

Résolvez-le correctement en utilisant la méthode de Jasen mentionnée ci-dessous.

ajouter curl.cainfo=/etc/ssl/certs/ca-certificates.crt à votre php.ini

Octobre 2017 edit:

Il existe maintenant un package de composition qui vous aide à gérer les certificats ca, afin que vous ne soyez pas vulnérable si votre cacert.pem devient obsolète à cause de la révocation de certificats.

https://github.com/paragonie/certainty -> composer require paragonie/certainty:dev-master

97
SchizoDuckie

Remarque: Ceci est strictement pas utilisation de production. Si vous voulez déboguer rapidement, cela peut être utile. Sinon, veuillez utiliser la réponse de @ SchizoDuckie ci-dessus. 

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);     
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 

Ajoutez-les simplement. Ça marche. 

28
mixdev

Vient d'avoir un problème très similaire et l'a résolu en ajoutant

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

Apparemment, le site sur lequel je vais chercher des redirections et php-curl ne suit pas les redirections par défaut.

6
Cobra_Fast

J'ai eu une situation où cela a aidé: (PHP 5.4.16 sur Windows)

curl_setopt($ch, CURLOPT_SSLVERSION, 3);
4
user203319

Chaque fois que je teste quelque chose avec PHP/Curl, je l’essaye d’abord en ligne de commande, découvre ce qui fonctionne, puis transfère mes options à PHP.

3
Issac Kelly

Parfois, vous devez mettre à niveau vos certificats Curl vers la dernière version pour éviter les erreurs avec https.

2
Elzo Valugi

J'ai utilisé file_get_contents à l'aide de stream_create_context et cela fonctionne bien:

$postdataStr = http_build_query($postdataArr);

$context_options = array (
        'http' => array (    <blink> // this will allways be http!!!</blink>
            'method' => 'POST',
            'header'=> "Content-type: application/x-www-form-urlencoded\r\n"
                . "Content-Length: " . strlen($postdataArr) . "\r\n"
                . "Cookie: " . $cookies."\r\n"
            'content' => $postdataStr
            )
        );

$context = stream_context_create($context_options);
$HTTPSReq = file_get_contents('https://www.example.com/', false, $context);
1
adyphp

Le meilleur moyen d'utiliser https et d'éviter les problèmes de sécurité est d'utiliser Firefox (ou un autre outil) et de télécharger le certificat sur votre serveur. Cette page m'a beaucoup aidé , et voici les étapes qui ont fonctionné pour moi:

1) Ouvrez dans Firefox l'URL que vous allez utiliser avec CURL

2) Dans la barre d’adresse, cliquez sur padlockname__> more information (les versions FF peuvent avoir différents menus, il suffit de le trouver). Clique le View certificate bouton> onglet Detailsname__.

3) Mettez en surbrillance le certificat "droit" dans Certificate hierarchy. Dans mon cas, il s’agissait du deuxième de trois, appelé "Autorité de certification cPanel, Inc.". Je viens de découvrir le bon par "essai et erreur" méthode.

4) Cliquez sur le Export bouton. Dans mon cas, celui qui travaillait était le type de fichier "PEM avec chaînes" (encore une fois par méthode d'essai et d'erreur).

5) Ensuite, dans votre script PHP, ajoutez:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);    
curl_setopt($ch, CURLOPT_CAINFO, [PATH_TO_CRT_FILE]);

De plus, je dirais que nous devons faire attention au fait que ces étapes devront probablement être refaites une fois par an ou chaque fois que le certificat d'URL est remplacé ou renouvelé.

0
Heitor

il se peut que votre hébergeur Web, où vous testez la communication sécurisée pour passerelle, rencontre un problème qui pourrait vous empêcher de le faire.

de plus, un nom d'utilisateur, un mot de passe doit être fourni avant la connexion à l'hôte distant.

ou votre IP doit éventuellement figurer dans la liste des adresses IP approuvées du serveur distant pour que la communication puisse être lancée.

0

J'ai découvert cette erreur sur un projet d'application récent. J'écrivais pour s'exécuter à partir de la ligne de commande ou de la fenêtre du navigateur. J'utilisais donc la détection de serveur pour obtenir l'URL relative du document que je demandais. Le problème était, le site est https, et chaque fois que j'ai essayé d'accéder à http: // (same server), cURL l'a utilement changé en https.

Cela fonctionne bien à partir du navigateur, mais à partir de la ligne de commande, j'obtiendrais alors une erreur SSL même lorsque les deux vérifications sont définies sur false. Ce que je devais faire était, 

1) Vérifiez $ _SERVER ['HTTP_Host']. Si présent, utilisez ($ _SERVER ['HTTPS']? "Https: //": "http: //"). $ _ SERVER ["HTTP_Host"]

2) Vérifiez $ _SERVER ['ORDINATEUR'] et, s'il correspond au serveur de production, indiquez l'URL https. (" https: // (nom du serveur) ")

3) Si aucune condition n'est satisfaite, cela signifie que j'exécute la ligne de commande sur un autre serveur et que j'utilise " http: // localhost ".

Maintenant, cela a fonctionné, mais c'est un hack. De plus, je n’ai jamais compris pourquoi cURL avait changé mon adresse URL sur un serveur (https), tandis que l’autre (https) l’avait laissée seule. 

Bizarre.

0
Michael