How to validate Google reCaptcha / noCaptcha in PHP?

Asked

Viewed 5,046 times

4

How to send such POST that Google asks and so make my field validated?

  • 2

    This reply may be related to: http://answall.com/a/60071/23400

  • 1

    @gustavox is related but is an alternative method (for me this related validation $resposta.success did not work), so I created my own validating a array PHP instead of a object JSON. It may not have worked because I use Codeigniter 3, but it is an alternative and objective way for those who only want to validate reCaptcha. ^^

2 answers

5


You send the POST method with the necessary data to google and receives content in PHP Array as follows:

    $captcha = $_POST['g-recaptcha-response'];
    $response = json_decode(file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=<SUA SITE KEY>&response=" . $captcha . "&remoteip=" . $_SERVER['REMOTE_ADDR']), TRUE);

g-recaptcha-response is the variable $_POST that your reCaptcha will create.

file_get_contents(...) is a function that executes the file and expects the file to give results as return to it. In this case we call a Google validator through the link and give value to it the values needed to operate and it returns us the following in JSON:

{
  "success": true|false,
  "error-codes": [...]   // optional
}

json_decode('...', TRUE) transforms the object JSON in array PHP. If the second value (in the syntax TRUE) for FALSE we will receive a object instead of array.

You can now validate like any other array in PHP:

if ($response['success'] == FALSE) {
        // Maldito spammer!
        return FALSE;
    } else {
        // Nice user
        return TRUE;
    }

Good studies! :)

2

If it doesn’t work with file_get_contents (as happened on my hosting server). There is a library on github, but I implemented with cURL. Was basically like this:

# Os parâmetros podem ficar em um array
$vetParametros = array (
    "secret" => "SUA-CHAVE-SECRETA",
    "response" => $_POST["g-recaptcha-response"],
    "remoteip" => $_SERVER["REMOTE_ADDR"]
);
# Abre a conexão e informa os parâmetros: URL, método POST, parâmetros e retorno numa string
$curlReCaptcha = curl_init();
curl_setopt($curlReCaptcha, CURLOPT_URL,"https://www.google.com/recaptcha/api/siteverify");
curl_setopt($curlReCaptcha, CURLOPT_POST, true);
curl_setopt($curlReCaptcha, CURLOPT_POSTFIELDS, http_build_query($vetParametros));
curl_setopt($curlReCaptcha, CURLOPT_RETURNTRANSFER, true);
# A resposta é um objeto json em uma string, então só decodificar em um array (true no 2º parâmetro)
$vetResposta = json_decode(curl_exec($curlReCaptcha), true);
# Fecha a conexão
curl_close($curlReCaptcha);
# Analisa o resultado (no caso de erro, pode informar os códigos)
if ($vetResposta["success"]) echo "<p>Captcha OK!</p>\n";
else 
{
    echo "$<p>Problemas:</p>\n";
    foreach ($vetResposta["error-codes"] as $strErro) echo "$strTab<p>Erro: $strErro</p>\n";
}

I didn’t see the benefit of using the library, but if you want to see, there’s a related article where I answered both options.

  • Sorry, but it works, I don’t have the project running on my server, but the way marked as correct worked. But thanks for the tip.

  • I didn’t even remember it was my own answer, so it might complicate, but anything we’re in...

  • 1

    Machado, you gave the answer in this article and another user, Rafael Almeida, gave the answer in another article on the same subject, both based on file_get_contents and about 6 months ago. I believe that at the time it worked and maybe it still works today. reCAPTCHA says it has to be POST, but Google documentation isn’t always 100%.

  • I even apologize for saying that it doesn’t work. I’ll even edit my reply. The important thing is to exchange information. I did tests as follows: with file_get_contents on my hosting server (Hostmedia). So it sure didn’t work. Any URL invoked in the function returned an empty string. It made no difference to put the incorrect key etc. Only maybe the function is disabled on the server. Anyway, by default the function uses GET (the parameters are in the URL) and using the POST is a little more secure (for example, it does not appear in logs).

  • I’m going to do some more tests. Then I found a hint in the PHP help saying how to do a POST with file_get_contents. I’ll do it on my machine, because maybe my hosting server blocks that function for some reason. The main goal is that we all learn a little more! Thank you!

  • 1

    AS PROMISED: I did more tests. Hosted on my PC, it works perfectly with file_get_contents. Later I found out why it doesn’t work in my hosting (Hostmídia): looking at the logs, I found that it is configured with allow_url_fopen=0 in PHP.ini. I tried ini_set('allow_url_fopen', 1), but it didn’t help. Regarding the question whether sending is by GET or POST: on my computer, I used Wireshark to analyze traffic, but I saw no problem, I think the function already encrypts everything before sending. The only problem is staying clear in the log when there is an error.

  • 1

    In other words, if you use any hosting that blocks the file_get_contents, there is no way, have to use another code, as the cURL. Anyway, as the parameters are passed to PHP in the URL, if there is any error or Warning, can be saved in the log with your key clear, which doesn’t seem cool.

  • 1

    NOTE: if someone wants to check the JS before sending it to PHP: if (grecaptcha.getResponse() == "") //Usuário não clicou no reCAPTCHA

  • Ah, interestingly, I will search my machine for the project and return you more information, as you said the documentation is not 100% and there are always obstacles to users regarding very large Apis. See you around.

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.