Link to home
Start Free TrialLog in
Avatar of trevor1940
trevor1940

asked on

How to validate Googles reCAPTCHA

Hi

I'm not a big fan of Googles reCAPTCHA  having clicked on 100's images of traffic lights, bicycles  and fire hydrants to be asked please try again

However can someone explain how  to validate it prior to submitting a form?

I'm assuming this is done within a JavaScript onSubmit function ??

I'm also assuming Is there no PHP  validation as reCAPTCHA  is a JavaScript library so if   isn't enabled reCAPTCHA   wont work


The code bellow is just to get going
<?php
error_reporting(E_ALL); 
$submit = filter_input(INPUT_POST, "submit");
if($submit){
  // validate form 
  $html = "<div>Hello Thank you for your message</div>";
  }
 
?>

<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
  <head>
    <meta charset="UTF-8">
    <title>Send a Message</title>
    <script src='https://www.google.com/recaptcha/api.js'></script>
      <script>
    function onSubmit() {
      document.getElementById("MyForm").submit();
    }
  </script>
  </head>
  <body>
    <?php
    if ($html){
    echo $html;
      }
    else
      {
      
      
    ?>
    <div class="FormWrap">

          
  <fieldset>

          
    <legend>Email Form</legend> 

          
      <form id="MyForm" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">

          
      <p><label for="Fname">Enter full name</label><input type="text" name="Fname" id="Fname" placeholder="Name" required="true"></p >

          
      <p><label for="email">Enter Email</label><input type="email" name="email" id="email" placeholder="Enter email" required="true"></p >

          
      <p><label for="msg">Enter Message<textarea id="msg" name="msg" required="true" placeholder="Talk to me" rows="15"></textarea></label> </p >
      <div class="g-recaptcha" data-sitekey="xxxxxxxxxxxxxxxxxx"></div>
      
        <button
            data-callback="onSubmit" name="submit" >Submit</button>
   

          
    </form >

          
  </fieldset >

          
</div> 

    <?php
      }
      ?>
  </body>
</html>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Olaf Doschke
Olaf Doschke
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of trevor1940
trevor1940

ASKER

Hi Olaf

I'mn confuse by the post contents of a submitted form

I created a GetForm.php and pasted  your code into it adding my "Secret key"

doing a var_dump of $_POST

[g-recaptcha-response] =>  Really long  random generated string


Your code

 $context  = stream_context_create($options);
  $result = file_get_contents($url, false, $context);
  if ($result === FALSE) { 
    $recaptchajson="didn't work"; 
  } else { 
    $recaptchajson=$result; 
  }
echo $recaptchajson ."<br />";

prints 
"didn't work"

Open in new window


If submit the form with reCaptcha Unticked

[g-recaptcha-response] => empty
You just took a part of my code. The important point is that you post the value your form got as input.

$data = array('secret' => '....secret token you got from Google...',
              'response' => $_POST["g-recaptcha-response"],
			  'remoteip' => $_SERVER["REMOTE_ADDR"]);

Open in new window


If your HTML form doesn't use POST but the GET method, you get the g-recaptcha-response as $_GET["g-recaptcha-response"] instead, but your HTML tells it uses method="post".

Not sure what's not working, but if you have only integrated the part of the code you reposted, you didn't post to Googles URL https://www.google.com/recaptcha/api/siteverify. Which version of reCaptcha are you using?

Bye, Olaf.
Hi,

you can use this reCAPTCHA PHP client library which is very popular (now compatible with v3)
https://github.com/google/recaptcha

It is recommended to use reCAPTCHA v. 3
https://www.google.com/recaptcha/intro/v3.html
Hi Olaf

My GetForm.php contains all your code I didn't see the point in reposting it all just the response from google  (see bellow)

so it sends the entire $data array to google but $result === false Therefore "Didn't Work"

I'm using V3

Your Code (Edited) I'm echoing messages instead of redirecting whilst testing

<?php

    echo "trace post<br />";
    trace($_POST);
    $html;
// validate form 
  if (empty($_POST["g-recaptcha-response"]))
{
//  header('Location:', '/botresponse.html'); // you might respond with 404 error, too, whatever.
//  exit;
    $html .= "g-recaptcha-response empty<br />";
} else {
  $url = 'https://www.google.com/recaptcha/api/siteverify';
  $data = array('secret' => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX',
              'response' => $_POST["g-recaptcha-response"],
			  'remoteip' => $_SERVER["REMOTE_ADDR"]);

  $options = array(
        'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data)
    ));
	
  $context  = stream_context_create($options);
  $result = file_get_contents($url, false, $context);
  if ($result === FALSE) { 
    $recaptchajson="didn't work<br />";
  } else { 
    $recaptchajson=$result; 
  }
echo $recaptchajson ."<br />";
  $recaptcha = json_decode($recaptchajson);
  echo $recaptcha ."<br />";
  if (!$recaptcha->success) {
//	header('Location: '/botresponse.html')
//	exit;
    $html .= "Not recaptcha sucess<br />";
    }
   else {

    // normal response, reCAPTCHA passed
    $html .= "<div>Hello Thank you for your message</div>";
    }

  
  
  }
  echo $html;
  
echo "Var Dump options<br />";
  trace($options);
  
  function trace($arr){
    echo "<pre>";
    print_r($arr);
    echo "</pre>";
}//end trace

Open in new window


this is what I get from your code when echoed at places  I'ved removed the Secret bits


Var Dump post

Array
(
    [Fname] => Trevor
    [email] => me@my.net
    [msg] => Hello World
    [g-recaptcha-response] => Very Long string
    [submit] => 
)

Var Dump options
Array
(
    [http] => Array
        (
            [header] => Content-type: application/x-www-form-urlencoded

            [method] => POST
            [content] => secret=xxxxxxxxxxxxxxxxxxxxxx&response=Very Long string&remoteip=XX.XXX.XX.XX
        )

)

echo $recaptchajson

didn't work


Not recaptcha sucess

Open in new window



lenamtl  I can't install PHP client library  on live server
This is for V2 of reCAPTCHA, but that part is the same in V3, just the JSON result has another structure and adds a score.

Perhaps $result = file_get_contents($url, false, $context) fails for other reasons, i.e. your hoster disallows it.

Please visit http://ptsv2.com, click on "New Random Toilet" and take the post URL given there as $url in the following code:

<?php
$url = 'http://ptsv2.com/...';
$data = array('parameter' => 'test');
$options = array(
        'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data)
    ));
	
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result===FALSE)
{
echo "your hosting doesn't allow to make http requests.";
} else {
echo $result;
}
?>

Open in new window


The result should be "Thank you for this dump. I hope you have a lovely day!" and on the given URL you should find data about your POST test request. If that works the Google reCAPTCHA verification URL should also work. Otherwise, your hosting is not only insufficient for adding a library on the server. You're restricted to make use of such an API and that needs to be done server-side.

Bye, Olaf.
Olaf

Please visit http://ptsv2.com, click on "New Random Toilet"
 
No idea what this is I get "The server at ptsv2.com is taking too long to respond." similar in chrome

I added this

  $context  = stream_context_create($options);
  $result = file_get_contents($url, false, $context);
   echo "<br />$url <br /> false <br /> $context <br />"; // new line

Open in new window


I get
https://www.google.com/recaptcha/api/siteverify
false
Resource id #1 

Open in new window


Which suggests $context is wrong??
The sample code is just created to test whether you can make a POST request at all, without any specific parameters, just anything. You could also try with the target URL of your form itself, but better test with an external target URL.

This is not meant to be integrated in your form GetForm.php, just a separate new test.php, you just need a target URL expecting a POST request and http://ptsv2.com -> "New Random Toilet" is creating such a target URL ("Post URL").

Another place I'd look into is the error.log of your server.

Bye, Olaf.
To clarify, I use the code about the reCAPTCHA verification 1:1 as is (except of the botresponse URL), so there is nothing wrong about the structure of that, the $data or $context composition, etc. But since your $result is FALSE, something isn't working for you, i.e. your server may not allow to use file_get_contents() to make a POST request. If the reason is not only this function but overall no permission to use third-party APIs from the server, you can't use Google reCAPTCHA.

Bye, Olaf.
Hi Olaf

Your Toilet flushed today and was able to run your code

and returning "your hosting doesn't allow to make http requests. "

The log file

[13-Nov-2018 11:42:24 Europe/London] PHP Deprecated:  Directive 'magic_quotes_gpc' is deprecated in PHP 5.3 and greater in Unknown on line 0
[13-Nov-2018 11:42:24 Europe/London] PHP Warning:  file_get_contents() [<a href='function.file-get-contents'>function.file-get-contents</a>]: http:// wrapper is disabled in the server configuration by allow_url_fopen=0 in /home/trevor/public_html/crap/olaf.php on line 25
[13-Nov-2018 11:42:24 Europe/London] PHP Warning:  file_get_contents(http://ptsv2.com/t/tocc1-1542108945/post) [<a href='function.file-get-contents'>function.file-get-contents</a>]: failed to open stream: no suitable wrapper could be found in /home/trevor/public_html/crap/olaf.php on line 25

Open in new window


Tried to set   allow_url_fopen=1 from here

Still fails

<!DOCTYPE html>
<!--
Http request test
-->
<html>
  <head>
    <meta charset="UTF-8">
    <title>Http request test</title>
  </head>
  <body>
    <?php
    ini_set('allow_url_fopen', '1');
    if (ini_get("allow_url_fopen") ==1) {
 echo "allow_url_fopen is ON<br />";
 } else {
  echo "allow_url_fopen is OFF<br />";
}
    
    $url = 'http://ptsv2.com/t/tocc1-1542108945/post';
$data = array('parameter' => 'test');
$options = array(
        'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data)
    ));
	
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result===FALSE)
{
echo "your hosting doesn't allow to make http requests.";
} else {
echo $result;
}

    ?>
  </body>
</html>

Open in new window


Any suggestion?
The solution is at your hands:

http:// wrapper is disabled in the server configuration by allow_url_fopen=0

If you have control about php.ini then allow to open urls by setting allow_url_fopen=1, if you have no control of this, you can't use the reCAPTCHA API.

The next big hurdle could become Google using https and not just http.

Bye, Olaf.
Hi Olaf

I managed to get this working
I had to contact the WebHosting Support to reconfigure the server to enable various functions which took a while

Thanx for your help
Hi,

You can install the library without composer if you want (basically just copy paste the folder and set config)
https://github.com/google/recaptcha#direct-download