Search code examples
phpserverrecaptcha

Basic server integration of recaptcha v2


Could anybody help me with this? I have been trying for months but only come across confusing information on YouTube and Google etc.

I'm building a subscription form for a newsletter. It's only an e-mail field and a submit button. I got a very simple php code for the form that works fine, but without recaptcha it's exposed to bots:

<?php $email = $_POST['email'];
$formcontent="From: $email \n";
$recipient = "contact@myemail.com";
$subject = "Subscribe";
$mailheader = "From: $email \r\n";
mail($recipient, $subject, $formcontent, $mailheader) or die("Error!");
echo "You have subscribed. You may close this tab now etc etc.";
?>

That's all I need. This code is on a mail.php file and I'm using action="mail.php" in the form, which is on a separate html-file.

Can anybody suggest additional code for me simply to add the SecretKey and do some basic server integration of recaptcha? I can't make any sense of the Google information website. They use terms I've never come across with. I have no idea what they are trying to say.


Solution

  • Provided you have the recaptcha working on the form then on submitting the form the $_POST in PHP will have 'g-recaptcha-response'. You can then use curl to make the API request to Google to verify their response.

    The following is the very basics and is UNTESTED. You will want to do a lot more work on this to improve the user experience, e.g. using Ajax

    <?php
    
    function verifyRecaptcha($response)
    {
      //Replace the below with your secret key
      $recaptchaSecret = '<google_recaptcha_secret_key>';
    
      $ch = curl_init('https://www.google.com/recaptcha/api/siteverify');
    
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_POSTFIELDS, array(
          'secret' => $recaptchaSecret,
          'response' => $response,
      ));
    
      $output = curl_exec($ch);
      curl_close($ch);
    
      //the response from Google will be a json string so decode it
      $output = json_decode($output);
    
      //one of the response keys is "success" which is a boolean
      return $output->success;
    }
    
    //First filter the POSTed data
    $email = filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL);
    $captchaResponse = filter_input(INPUT_POST,'g-recaptcha-response',FILTER_SANITIZE_STRING);
    
    //If either email or catcha reponse is missing then one or both were not completed before submit
    if(empty($email) || empty($captchaResponse))
    {
      //TODO: Better error handling here
      echo "There was an error with the submitted data.";
    }
    elseif(!verifyRecaptcha($captchaResponse))  //this calls the above function to make the curl request
    {
      //TODO: Better error handling here
      echo "Recaptcha verification failed.";
    }
    else
    {
      //I would suggest you don't use their email as the "From" address, rather it should be a domain
      //that is allowed to send email from the server
      //Instead you want to use their email as the "Reply-To" address
      $formcontent = "From: $email \n";
      $recipient = "contact@myemail.com";
      $subject = "Subscribe";
      $mailheader = "From: $email \r\n";
      mail($recipient, $subject, $formcontent, $mailheader) or die("Error!");
      echo "You have subscribed. You may close this tab now etc etc.";
    }