PHP CURL和HTTPS


70

我发现此功能确实出色(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;
}

我唯一的问题是它不适用于https://。Anny的想法,我需要做些什么才能使https工作?谢谢!



3
默认情况下卷曲,检查SSL证书是否有效...如果您对有问题的证书进行自我签名,则可能要禁用该行为
RageZ 2010年

@RegeZ-如何提出您的建议?
StackOverflowNewbie 2010年


标记为正确的答案不应是正确的答案。
加文·帕尔默

Answers:


115

快速修复,在您的选项中添加:

curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false)

现在,您不知道您实际上要连接到哪个主机,因为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
        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;
}

2
这里有更多这方面的信息:unitstep.net/blog/2009/05/05/...
SystemX17

没关系-从昨天开始我才是新来的。感谢您为提出要求的人提供了更好的代码-真棒。
SystemX17 2010年

27
将CURLOPT_SSL_VERIFYPEER设置为false允许中间人攻击。webaware dot com dot au上的rmckaynl3.php.net/manual/en/function.curl-setopt.php对此发出警告,并提供了一种可行的替代解决方案:在curl网站上下载CA根证书捆绑包并将其保存在您的服务器。在给定的站点上查看,向下滚动到用户评论。
PaulGobée2014年

36

我试图用CURL用php做一些https API调用,并遇到了这个问题。我在php网站上发现了一条建议,该建议使我开始运行:http : //php.net/manual/en/function.curl-setopt.php#110457

请大家,停止将CURLOPT_SSL_VERIFYPEER设置为false或0。如果您的PHP安装中没有最新的CA根证书捆绑包,请在curl网站上下载该证书并将其保存在服务器上:

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

然后在您的php.ini文件中,例如在Windows上,为它设置一个路径:

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

关闭CURLOPT_SSL_VERIFYPEER将允许中间人(MITM)攻击,这是您不希望的!


3
我做到了,但现在我只能得到35 error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
OZZIE'Feb 1'1

5

像Gavin Palmer答案这样的另一个选择是使用.pem文件,但使用curl选项

  1. .pemhttps://curl.haxx.se/docs/caextract.html下载最后更新的文件,并将其保存在服务器上的某个位置(公用文件夹之外)

  2. 在代码而不是php.ini文件中设置选项。

在你的代码中

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

注意:php.ini像@Gavin Palmer那样设置cainfo比像在我的代码中那样设置cainfo更好,因为每次调用该函数时它都会节省磁盘IO,我只是这样做,以防您要测试即时更改cainfo文件,而不是php.ini在测试功能时更改。


1

一个重要的注意事项,上述解决方案在本地主机上不起作用,您必须将代码上传到服务器,然后它才能起作用。我没有收到错误,但请求错误,问题是我正在使用localhost(test.dev,myproject.git)。以上两种解决方案均有效,建议使用SSL证书的解决方案。

  1. 转到https://curl.haxx.se/docs/caextract.html,下载最新的cacert.pem。商店在某处(不在公用文件夹中-但无论如何都可以使用)

  2. 使用此代码

“。$ result; //回显”
路径:“。$ _ SERVER ['DOCUMENT_ROOT']。” /ssl/cacert.pem“; //仅用于故障排除吗?>
  1. 将代码上传到实时服务器并进行测试。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.