0
votes

I've created a website through Dreamweaver with a simple contact form to fire off an email. Previously it didn't have recaptcha and worked fine, sending an email and showing success/failure messages correctly. I've re-written it now using a Recaptcha v2 tick box, but now always get the error message "Invalid captcha", and no email. The page presents correctly. The captcha presents correctly and allows you to make the selections then click the verify button, resulting in the green tick. However, when clicking the send button, it always fails.

Any help gratefully accepted.

Live website: https://www.simpleenglish.info/en/contact_us/contact_form.php

I confirm the site key and secret key are correct, as are all email addresses. I have deleted and created the keys and associated the domain through google admin twice, without success. I believe the code to be correct (no obvious errors). I haven't found any similar problem here or Google Groups to point me in a direction. I don't know where else to look.

The contact_form.php code (now complete):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><!-- InstanceBegin template="/Templates/SE1.dwt" codeOutsideHTMLIsLocked="false" -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- InstanceBeginEditable name="doctitle" -->
<title>Simple English Contact</title>

<script src="https://www.google.com/recaptcha/api.js"></script>
<!-- InstanceEndEditable -->

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-136785269-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-136785269-1');
</script>

<script>
  (adsbygoogle = window.adsbygoogle || []).push({
    google_ad_client: "ca-pub-1086244781484067",
    enable_page_level_ads: true
  });
    </script>

    <link href="https://www.simpleenglish.info/SE_3ColLiquid.css" rel="stylesheet" type="text/css" /><!--[if lte IE 7]>
    <style>
    .content { margin-right: -1px; } /* this 1px negative margin can be placed on any of the columns in this layout with the same corrective effect. */
    ul.nav a { zoom: 1; }  /* the zoom property gives IE the hasLayout trigger it needs to correct extra whiltespace between the links */
    </style>
<![endif]-->
<!-- InstanceBeginEditable name="head" -->
<!-- InstanceEndEditable -->
</head>

<body>

<div class="container">

  <div class="sidebar1"> <a href="https://www.simpleenglish.info/index.html"><img src="/images/logo.jpg" alt="Simple English Logo" width="99%"/></a>
    <ul class="nav" >      
      <li><a href="https://www.simpleenglish.info/index.html">Home</a></li>
      <li><a href="https://www.simpleenglish.info/en/vocabulary.html">Vocabulary</a></li>
      <li><a href="https://www.simpleenglish.info/en/usefullinks.html">Useful Links</a></li>
      <li><a href="https://www.simpleenglish.info/en/teachersaids.html">Teacher's Aids</a></li>
      <li><a href="https://www.simpleenglish.info/en/contact_us/contact_form.php">Contact us</a></li>
      <li><a href="https://www.simpleenglish.info/en/sitemap.html">Site Map</a></li>
    </ul>
</div>

  <div class="content">
    <img src="https://www.simpleenglish.info/images/title.jpg" width="99%" alt="Simple English Title"/>
    <br />
    <br />
    <!-- InstanceBeginEditable name="EditRegionContent" -->
    <h1 class="pageheader">Contact Us</h1> 
    <p>To send us a message, please enter <strong>all the information</strong> in the following form, then click the 'Send' button.</p> 

      <div class="contact_us"> 
          <form method="post" action="" accept-charset="UTF-8"> 
              <table> 
                  <tr><td>Name:</td><td><input type="text" name="sendername" placeholder="Enter your full name" size="50" required="required"/></td></tr> 
                  <tr><td>Email:</td><td><input type="email" name="senderemail" placeholder="Enter your email address" size="50" required="required"/></td></tr> 
                  <tr><td>Message Context:</td><td><input type="text" name="sendercontext" placeholder="this will be context" size="50" required="required"/></td></tr> 
                  <tr><td>Message:</td><td><textarea name="sendermessage" rows="5" cols="50" placeholder="How can we help you?" required="required"></textarea></td></tr> 
                  <tr><td>Spam Check:</td><td><div class="g-recaptcha" data-sitekey="XXX Correct Key XXX"></div></td></tr> 
                  <tr><td></td><td><input type="submit" name="submit" value="Send" class="submit-btn"/></td></tr>
              </table> 
          </form> 

          <div class="status"> 
              <?php if(isset($_POST['submit'])) 
               { 
                $user_name = $_POST['sendername']; 
                $user_email = $_POST['senderemail']; 
                $user_context = $_POST['sendercontext']; 
                $user_message = $_POST['sendermessage']; 

                $email_from = '[email protected]'; 
                $email_subject = "Simple English Contact"; 
                $email_body = "Name: $user_name.\n". 
                          "Email: $user_email.\n". 
                          "Context: $user_context.\n". 
                          "Message: $user_message.\n"; 
                $to_email = "[email protected]"; 
                $header = "From: $email_from \r\n"; 
                $header .= "Reply-To: $user_email \r\n"; 
                $secretkey = "XXX Correct Key XXX"; 
                $responsekey = $_POST['g-recaptcha-response']; 
                $userip = $_SERVER['REMOTE_ADDR']; 
                $url = "https://www.google.com/recaptcha/api/siteverify?secret=$secretkey&response=$responsekey&remoteip=$userip"; 

                $response = file_get_contents($url); 
                $response = json_decode($response); 

            if($response->success) 
            { 
                mail($to_email,$email_subject,$email_body,$header); 
                echo "Message sent successfully"; 
            } 
            else 
            { 
                echo "Invalid Captcha. Please try again."; 
            } 
           } 
          ?> 
      </div> 
  </div>   

<p>&nbsp;</p>
<p>&nbsp;</p>
<!-- InstanceEndEditable -->
<p>&nbsp;</p>
<!-- end .content --></div>

<div class="sidebar2">
<h4>&nbsp;</h4>
<p>&nbsp;</p>
<!-- end .sidebar2 --></div>

<div class="footer">
<p>Copyright © 2018<br />
   All rights reserved <!-- end .footer --></p>
</div>
<!-- end .container --></div>
</body>
<!-- InstanceEnd --></html>
2
Do a var_dump on $response and see what google is returning? Haven't used v2 in a while but the docs say the Method should be POST have you tried that? - Second2None
Second2None, thanks for spotting that "POST". I've made the change, but no luck. I'll run a var_dump, but TBH don't know what I'm looking for. - Mark
Do you want to post the code you tried for POST? Also what did $response return? - Second2None
I'm not sure how to post the code here, these comments have a char limit. If you can tell me how, I'll do it. The result from the var_dump was "NULL" . Although by playing around, in one test I also got "bool(false)". As said previously, I don't know what these mean, but I hope that helps you ? - Mark
you can just edit your question and add it to the bottom. file_get_contents returns false on failure, do var_dump($response) before you convert it to json, json_decode returns NULL on invalid json. I checked your form and g-recaptcha-response is being sent correctly. I'll post an answer below with how I normally check using file_get_contents - Second2None

2 Answers

0
votes

Your div tag for the recaptcha is not closed off properly. Do view page source and you'll see it in the table row.

<tr><td>Spam Check:</td><td><div class="g-recaptcha" data-sitekey="6Lc8OZ8UAAAAABUosvouUbamfotW9Pp-9ioRIEOZ"></td></tr>
0
votes

Because I use classes I put this into a function. Google expects the method to be POST. You can do this with file_get_contents by setting stream_context_create options.

The rest is pretty self explanatory, $secretkey is your recaptcha secret key and $captcha is your $_POST['g-recaptcha-response']

https://www.php.net/manual/en/function.stream-context-create.php

function checkRecaptcha( $secretkey , $captcha ){

    $url = 'https://www.google.com/recaptcha/api/siteverify';
    $data = [
        'secret' => $secretkey , 
        'response' => $captcha ,
        'remoteip' => $_SERVER['REMOTE_ADDR'] ,
    ];
    $options = [
        'http' => [
          'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
          'method'  => 'POST',
          'content' => http_build_query( $data )
          ]
    ];
    $context  = stream_context_create( $options );
    $contents = file_get_contents( $url , false , $context );
    $response = json_decode( $contents , true ); //convert to assoc array
    // if you want to use objects, remove true from json decode and then use $response->success
    if( ! $response["success"] ) { 
        return false;
    }
    return true;
}

You can then use it like:

<?php

function checkRecaptcha( $secretkey , $captcha ){

    $url = 'https://www.google.com/recaptcha/api/siteverify';
    $data = [
        'secret' => $secretkey , 
        'response' => $captcha ,
        'remoteip' => $_SERVER['REMOTE_ADDR'] ,
    ];
    $options = [
        'http' => [
            'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
            'method'  => 'POST',
            'content' => http_build_query( $data )
            ]
    ];
    $context  = stream_context_create( $options );
    $contents = file_get_contents( $url , false , $context );
    $response = json_decode( $contents , true ); //convert to assoc array
    // if you want to use objects, remove true from json decode and then use $response->success
    if( ! $response["success"] ) { 
        return false;
    }
    return true;
}

if( isset($_POST['submit'] ) ) {

    $secretkey = "XXX Correct key here XXX";

    if( ! checkRecaptcha( $secretkey , $_POST['g-recaptcha-response'] ) ) {

        //only set variables if passes recaptcha

        //validate email address
        if ( ! filter_var( $_POST['senderemail'] , FILTER_VALIDATE_EMAIL)) {
            echo "Please provide a valid email";
            die();
        }

        //ensure user doesn't post HTML
        $user_name = strip_tags ( $_POST['sendername'] ); 
        $user_context = strip_tags ( $_POST['sendercontext'] );
        $user_message = strip_tags ( $_POST['sendermessage'] );

        $email_body = "Name: $user_name.\n"."Email: {$_POST['senderemail']}.\n"."Context: $user_context.\n"."Message: $user_message.\n";

        $header = "From: [email protected] \r\n";
        $header .= "Reply-To: {$_POST['senderemail']} \r\n";

        mail( '[email protected]' , 'Simple English Contact' , $email_body , $header );
        echo "Message sent successfully";

    }else{

        echo "Invalid Captcha. Please try again.";

    }
}

?>