Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá! Esse erro ocorre em um php simples rodando em um servidor compartilhado Locaweb: SSL certificate problem: unable to get local issuer certificate. O php faz uma requisição ao site do Cep Aberto para consulta de endereço informando o CEP (https://www.cepaberto.com/api/v3/cep?cep=95020520)
Olhei o php.ini e não tem nenhuma menção ao arquivo de certificados. Então peguei alguns tutoriais, baixei o arquivo "cacert.pem", coloquei lá e defini o curl no próprio php, ficou assim:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Token token="' . $token . '"']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_CAINFO, $cacert);
curl_setopt($ch, CURLOPT_CAPATH, $cacert);
$res = curl_exec($ch);
if($res===FALSE) {
$Res["erro"] = "curl";
$Res["msg"] = "Execução CURL falhou!";
$Res["descr"] = curl_error($ch);
} else {
$Res["dados"] = json_decode($res);
$Res["http"] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$Res["erro"] = ($Res["http"]==200)? "OK" : "http" ;
$Res["msg"] = ($Res["http"]==200)? "" : "Erro HTTP ".$Res["http"] ;
}
Onde $cacert é o endereço do arquivo "cacert.pem", verificado antes por is_file. Mas o erro é o mesmo, como se eu nada tivesse feito. Tem que configura o Apache? Não sei como configurar o Apache, será que posso? Desabilitar o SSL do php é uma opção que não tentei ainda, dizem que não é aconselhável...
O PHP é o 5.6 (pretendo ir pro 7.4 em breve) e o servidor é CENTOS 5.11 compartilhado, hospedagem Locaweb.
Alguma ideia?Essa é a url: https://www.cepaberto.com/api/v3/cep?cep=95020520, mas tem que passar o token no header. De qualquer forma, o erro é local, vai dar erro em qualquer url com ssl.
Eu consegui o token e mesmo assim não consegui fazer o cURL funcionar. Eu sinto muito.
Mesmo assim, eu achei no Google outra forma de consultar o CEP:
<meta charset="utf-8">
<h1>Pesquisar Endereço</h1>
<form action="" method="post">
<input type="text" name="cep">
<button type="submit">Pesquisar Endereço</button>
</form>
<?php
function get_endereco($cep){
// formatar o cep removendo caracteres nao numericos
$cep = preg_replace("/[^0-9]/", "", $cep);
$url = "http://viacep.com.br/ws/$cep/xml/";
$xml = simplexml_load_file($url);
return $xml;}
if($_POST['cep']){
echo "<h2>Resultado da Pesquisa</h2><p>";
$endereco = get_endereco($_POST['cep']);
echo "<table>";
echo "<tr><td>CEP:<td>$endereco->cep";
echo "<tr><td>Logradouro:<td>$endereco->logradouro";
echo "<tr><td>Bairro:<td>$endereco->bairro";
echo "<tr><td>Localidade:<td>$endereco->localidade";
echo "<tr><td>UF:<td>$endereco->uf</table>"; }Oi boa noite! Tudo bem?
No caso qual o valor da variável $cacert ? Me mostra o caminho do certificado pois o ideal é usar o caminho absoluto tipo /var/www/html/certificados/arquivo.pem
...
curl_setopt($ch, CURLOPT_CAINFO, $cacert);
curl_setopt($ch, CURLOPT_CAPATH, $cacert);
...
Esse certificado que você está usando você baixou de um site aleatório ou é desta empresa da $url?
Se você quiser pode testar desativando a verificação do certificado (ssl) se não você precisa de um certificado válido no seu servidor para usar o que é o recomendado.
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Token token="' . $token . '"']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($ch, CURLOPT_CAINFO, $cacert);
//curl_setopt($ch, CURLOPT_CAPATH, $cacert);
$res = curl_exec($ch);
if($res===FALSE) {
$Res["erro"] = "curl";
$Res["msg"] = "Execução CURL falhou!";
$Res["descr"] = curl_error($ch);
} else {
$Res["dados"] = json_decode($res);
$Res["http"] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$Res["erro"] = ($Res["http"]==200)? "OK" : "http" ;
$Res["msg"] = ($Res["http"]==200)? "" : "Erro HTTP ".$Res["http"] ;
}>
1 hora atrás, André Severino disse:
Oi boa noite! Tudo bem?
No caso qual o valor da variável $cacert ? Me mostra o caminho do certificado pois o ideal é usar o caminho absoluto tipo /var/www/html/certificados/arquivo.pem
...
curl_setopt($ch, CURLOPT_CAINFO, $cacert);
curl_setopt($ch, CURLOPT_CAPATH, $cacert);
...
Esse certificado que você está usando você baixou de um site aleatório ou é desta empresa da $url?
Se você quiser pode testar desativando a verificação do certificado (ssl) se não você precisa de um certificado válido no seu servidor para usar o que é o recomendado.
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Token token="' . $token . '"']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($ch, CURLOPT_CAINFO, $cacert);
//curl_setopt($ch, CURLOPT_CAPATH, $cacert);
$res = curl_exec($ch);
if($res===FALSE) {
$Res["erro"] = "curl";
$Res["msg"] = "Execução CURL falhou!";
$Res["descr"] = curl_error($ch);
} else {
$Res["dados"] = json_decode($res);
$Res["http"] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$Res["erro"] = ($Res["http"]==200)? "OK" : "http" ;
$Res["msg"] = ($Res["http"]==200)? "" : "Erro HTTP ".$Res["http"] ;
}
Eu testei o código do André Veríssimo e deu certo. Aqui o código teste que eu fiz:
<?php
$url="https://www.cepaberto.com/api/v3/cep?cep=95020520";
$token="c4f34d1210626b65990f1b764a822552";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Token token="' . $token . '"']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($ch, CURLOPT_CAINFO, $cacert);
//curl_setopt($ch, CURLOPT_CAPATH, $cacert);
$res = curl_exec($ch);
$jes= json_decode($res,true); // testando a resposta
var_dump($jes); // testando a resposta
exit; // testando a resposta
if($res===FALSE) {
$Res["erro"] = "curl";
$Res["msg"] = "Execução CURL falhou!";
$Res["descr"] = curl_error($ch);
} else {
$Res["dados"] = json_decode($res);
$Res["http"] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$Res["erro"] = ($Res["http"]==200)? "OK" : "http" ;
$Res["msg"] = ($Res["http"]==200)? "" : "Erro HTTP ".$Res["http"]
}
e aqui a resposta:
C:\wamp64\www\astudy\astudy.php:13:
array (size=9)
'altitude' => float 817
'cep' => string '95020520' (length=8)
'latitude' => string '-29.1707900004' (length=14)
'longitude' => string '-51.1821951652' (length=14)
'logradouro' => string 'Rua Sinimbu' (length=11)
'bairro' => string 'São Pelegrino' (length=14)
'complemento' => string '- de 2151 ao fim - lado ímpar' (length=30)
'cidade' =>
array (size=3)
'ddd' => int 54
'ibge' => string '4305108' (length=7)
'nome' => string 'Caxias do Sul' (length=13)
'estado' =>
array (size=1)
'sigla' => string 'RS' (length=2)Sim, o que eu fiz foi desativar o SSL através das linhas citadas porque achei um preciosismo de segurança.
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
O ViaCEP também é uma opção, acho que estava fora do ar na época e eu acabei usando o CEP Aberto.
Porém, me preocupa o fato do CURL insistir em não carregar o arquivo. Podemos precisar em um projeto no futuro. Vou postar todo o código aqui, até como contribuição, não há tutorial em PHP no site CEP Aberto. O código permite fazer vários tipos de consulta a partir de um JavaScript e obter o retorno em JSON, mas também permite testes direto no navegador.
<?php
header('HTTP/1.1 200 OK');
header('Content-Type: text/plain; charset=utf-8');
define("ROOT", dirname(__FILE__)."/");
$api = (isset($_GET["api"]))? $_GET["api"] : FALSE ; // método: cep, nearest, address e cities
$req = (isset($_GET["req"]))? $_GET["req"] : FALSE ; // dados em json
$token = 'meusegredinho'; // token do CEP Aberto
$cacert = ROOT.'cacert.pem'; // Certificados SSL
//
$Res = ["erro"=>"OK", "msg"=>"", "dados"=>[], "url"=>"", "http"=>0, "descr"=>""];
//
if(is_file($cacert)) {
if($api && $req) {
$query = http_build_query(json_decode($req, TRUE));
$url = 'https://www.cepaberto.com/api/v3/'.$api.'?'.$query;
$Res["url"] = $url;
try {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Token token="' . $token . '"']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($ch, CURLOPT_CAINFO, $cacert);
//curl_setopt($ch, CURLOPT_CAPATH, $cacert);
$res = curl_exec($ch);
if($res===FALSE) {
$Res["erro"] = "curl";
$Res["msg"] = "Execução CURL falhou!";
$Res["descr"] = curl_error($ch);
} else {
$Res["dados"] = json_decode($res);
$Res["http"] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$Res["erro"] = ($Res["http"]==200)? "OK" : "http" ;
$Res["msg"] = ($Res["http"]==200)? "" : "Erro HTTP ".$Res["http"] ;
}
curl_close($ch);
} catch(Exception $e) {
$Res["erro"] = "?";
$Res["msg"] = "Erro desconhecido";
$Res["descr"] = $e;
}
} else {
$Res["erro"] = "params";
$Res["msg"] .= (!$api)? "Parâmetro api não informado " : "" ;
$Res["msg"] .= (!$req)? "Parâmetro req não informado " : "" ;
}
} else {
$Res["erro"] = "cacert";
$Res["msg"] = "Arquivo de certificados SSL não encontrado.";
$Res["descr"] = "Arquivo requerido não encontrado em '".$cacert."'.";
}
switch($_GET["teste"]){
case "txt":
echo("url: ".$url."\nerro: ".$Res["erro"]."\nmsg: ".$Res["msg"]."\nhttp: ".$Res["http"]."\ndados: \n".json_encode($Res["dados"], JSON_PRETTY_PRINT)."\ndescr: \n".json_encode($Res["descr"], JSON_PRETTY_PRINT));
break;
case "json":
default:
echo(json_encode($Res));
}
?>
<?php
header('HTTP/1.1 200 OK');
header('Content-Type: text/plain; charset=utf-8');
define("ROOT", dirname(__FILE__)."/");
$api = (isset($_GET["api"]))? $_GET["api"] : FALSE ; // método: cep, nearest, address e cities
$req = (isset($_GET["req"]))? $_GET["req"] : FALSE ; // dados em json
$token = 'c546794c1f405bf6e1b74aba4147cff1'; // token do CEP Aberto
$cacert = ROOT.'cacert.pem'; // Certificados SSL
//
$Res = ["erro"=>"OK", "msg"=>"", "dados"=>[], "url"=>"", "http"=>0, "descr"=>""];
//
if(is_file($cacert)) {
if($api && $req) {
$query = http_build_query(json_decode($req, TRUE));
$url = 'https://www.cepaberto.com/api/v3/'.$api.'?'.$query;
$Res["url"] = $url;
try {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Token token="' . $token . '"']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($ch, CURLOPT_CAINFO, $cacert);
//curl_setopt($ch, CURLOPT_CAPATH, $cacert);
$res = curl_exec($ch);
if($res===FALSE) {
$Res["erro"] = "curl";
$Res["msg"] = "Execução CURL falhou!";
$Res["descr"] = curl_error($ch);
} else {
$Res["dados"] = json_decode($res);
$Res["http"] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$Res["erro"] = ($Res["http"]==200)? "OK" : "http" ;
$Res["msg"] = ($Res["http"]==200)? "" : "Erro HTTP ".$Res["http"] ;
}
curl_close($ch);
} catch(Exception $e) {
$Res["erro"] = "?";
$Res["msg"] = "Erro desconhecido";
$Res["descr"] = $e;
}
} else {
$Res["erro"] = "params";
$Res["msg"] .= (!$api)? "Parâmetro api não informado " : "" ;
$Res["msg"] .= (!$req)? "Parâmetro req não informado " : "" ;
}
} else {
$Res["erro"] = "cacert";
$Res["msg"] = "Arquivo de certificados SSL não encontrado.";
$Res["descr"] = "Arquivo requerido não encontrado em '".$cacert."'.";
}
switch($_GET["teste"]){
case "txt":
echo("url: ".$url."\nerro: ".$Res["erro"]."\nmsg: ".$Res["msg"]."\nhttp: ".$Res["http"]."\ndados: \n".json_encode($Res["dados"], JSON_PRETTY_PRINT)."\ndescr: \n".json_encode($Res["descr"], JSON_PRETTY_PRINT));
break;
case "json":
default:
echo(json_encode($Res));
}
?>Oi que bom que conseguiu
>
Em 10/09/2022 at 15:37, gustavopinent disse:
Sim, o que eu fiz foi desativar o SSL através das linhas citadas porque achei um preciosismo de segurança.
O SSL está em nossa vida para melhorar a segurança de nossos sistemas e ajudar os usuários, não é um preciosismo, o ideal é usar várias camadas de segurança e usar um certificado válido faz parte de uma delas.
>
Em 10/09/2022 at 15:37, gustavopinent disse:
...
Porém, me preocupa o fato do CURL insistir em não carregar o arquivo. Podemos precisar em um projeto no futuro. ...
Se você passou o caminho do arquivo corretamente, ele está carregando sim. O problema é que você está usando um certificado inválido então ele não roda xD mas se você precisar usar no futuro basta usar um certificado válido e passar o caminho corretamente no curl.
Abraço e qualquer dúvida só postar xD
>
2 horas atrás, André Severino disse:
Oi que bom que conseguiu
Se você passou o caminho do arquivo corretamente, ele está carregando sim. O problema é que você está usando um certificado inválido então ele não roda xD mas se você precisar usar no futuro basta usar um certificado válido e passar o caminho corretamente no curl.
Abraço e qualquer dúvida só postar xD
Ocorre que o erro retornado pelo curl é o mesmo após feita a alteração, e remete ao arquivo local, não ao certificado do CEP Aberto. Mas vou manter isso em mente, especialmente quando a requisição for mais "séria". Eu achava que o php estava encontrando o arquivo mas não conseguia processá-lo de fato. Então é culpa do CEP Aberto? Na minha humilde opinião, eles não deveriam deixar assim, não ajuda a tornar a Internet mais segura.
Como você não passou a $url, eu usei $url="facebook.com", assim