php使用curl访问https

/** 
 * curl POST 
 * 
 * @param   string  url 
 * @param   array   数据 
 * @param   int     请求超时时间 
 * @param   bool    HTTPS时是否进行严格认证 
 * @return  string 
 */  
function curlPost($url, $data = array(), $timeout = 30, $CA = true){    

    $cacert = getcwd() . '/cacert.pem'; //CA根证书  
    $SSL = substr($url, 0, 8) == "https://" ? true : false;  

    $ch = curl_init();  
    curl_setopt($ch, CURLOPT_URL, $url);  
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);  
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout-2);  
    if ($SSL && $CA) {  
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);   // 只信任CA颁布的证书  
        curl_setopt($ch, CURLOPT_CAINFO, $cacert); // CA根证书(用来验证的网站证书是不是CA颁布)  
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 检查证书中是否设置域名,而且是否与提供的主机名匹配  
    } else if ($SSL && !$CA) {  
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书  
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 检查证书中是否设置域名  
    }  
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); //避免data数据过长问题  
    curl_setopt($ch, CURLOPT_POST, true);  
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);  
    //curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); //data with URLEncode  

    $ret = curl_exec($ch);  
    //var_dump(curl_error($ch));  //查看报错信息  

    curl_close($ch);  
    return $ret;    
}

若是URL地址是https打头,那就走SSL,不然就走普通的HTTP协议。php

是否走HTTPS的话就安全了吗?其实SSL也有不一样的验证程度。浏览器

例如需不须要验证证书中的公用名呢?(BTW:公用名(Common Name)通常来说就是填写你将要申请SSL证书的域名 (domain)或子域名(sub domain)。)安全

须要验证主机名吗?dom

是任何证书都信任呢仍是只信任CA颁布的呢?curl

(我擦嘞,电池快没点了,只捡关键地儿说了 - -|||)ide

若是网站SSL证书买的是CA的(一般比较贵),那么访问时可使用比较严格的认证,即:网站

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);   // 只信任CA颁布的证书 
curl_setopt($ch, CURLOPT_CAINFO, $cacert); // CA根证书(用来验证的网站证书是不是CA颁布) 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 检查证书中是否设置域名,而且是否与提供的主机名匹配

若是网站的证书是本身生成的,或者是网上的小机构申请的,那么访问时若是使用严格认证则不会经过,直接返回false。(对了,返回false时能够打印curl_error($ch)查看具体错误信息。)此时能够根据状况经过下降验证程度来保证正常访问,例如:ui

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 检查证书中是否设置域名(为0也能够,就是连域名存在与否都不验证了)


平时咱们使用浏览器访问各个https网站时,有时会遇到证书不受信的提示,其实就是由于这些网站的证书不是正规CA机构颁布的。url

市面上各类浏览器中都内置了CA根证书列表信息,访问有CA颁布证书的网站时,会根据根证书验证这些网站的证书,因此就不会有这个提示了。code

关于CA根证书文件,其实就是包含了各个主要CA机构的公钥证书,用来验证网站的证书是不是这些机构颁发的。

这里的这个文件是来源于mozilla的源码树,又转换成PEM格式证书文件。(你们能够到这里下载现成的http://curl.haxx.se/ca/cacert.pem)

最后说一个和SSL无关的东西:

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));

这个主要是为了解决POST时数据过长问题

相关文章
相关标签/搜索