2

I'm trying to implement the invisible reCaptcha onto a website. But I can not get it working. Here is what I'm doing:

header

  <!-- Invisible reCaptcha -->
  <script src="https://www.google.com/recaptcha/api.js" async defer></script>

form.php

<form id="contact-form" class="contact-form" action="#contact">
   <p class="contact-name">
     <input id="contact_name" type="text" placeholder="Full Name" value="" name="name" />
   </p>
   <p class="contact-email">
     <input id="contact_email" type="text" placeholder="Your E-Mail Address" value="" name="email" />
    </p>
     <p class="contact-message">
       <textarea id="contact_message" placeholder="Your Message" name="message" rows="15" cols="40"></textarea>
     </p>
     <p class="contact-submit">
       <a type="submit" id="contact-submit" class="submit" href="#">Send Your Email</a>
      </p>
       <div id="recaptcha" class="g-recaptcha"  data-sitekey="6LceN0sUAAAAAPvMoZ1v-94ePuXt8nZH7TxWrI0E" data-size="invisible" data-callback="onSubmit"></div>
       <div id="response">
       </div>
</form>

script.js

// contact form handling
  $(function() {
    $("#contact-submit").on('click',function() {
        $contact_form = $('#contact-form');

        var fields = $contact_form.serialize();
      var test = grecaptcha.execute();
      console.log(fields);
      console.log(test);

        $.ajax({
            type: "POST",
            url: "assets/php/contact.php",
            data: fields,
            dataType: 'json',
            success: function(response) {
                if(response.status){
                    $('#contact-form input').val('');
                    $('#contact-form textarea').val('');
                }

                $('#response').empty().html(response.html);
            }
        });
        return false;
    });
  });

contact.php

private function validateFields(){
        // Check reCaptcha
    if(!$this->captcha){
        echo "Please fill out the reCaptcha correctly";
     }

   $response=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secretkey."&response=".$this->captcha."&remoteip=".$_SERVER['REMOTE_ADDR']);
             if(intval($responseKeys["success"]) !== 1) {
                 echo "You are a bot! GO AWAY!";
            }

The backend (contact.php) is working fine, if g-recaptcha-response is not null. However my Problem is that g-recaptcha-response (in var fields and test) is always empty when I try to do it. When I show the recaptcha on the form and fill it out, the g-recapcha-response is not empty and everything works fine. I know that I must invoke the grecaptcha.execute() somewhere, but even if I do, the variable is empty. How do programmaticaly call the this?

I appreciate every help! Thank you in advance!

jor
  • 158
  • 1
  • 13
  • Are you missing the `data-callback` ? I believe the function for that is what gets the value you send (as the first param). Since you are posting your form through ajax, you may have to move the ajax portion into the callback function so it doesn't fire off too early (since the callback has no promise). – IncredibleHat Mar 07 '18 at 18:34
  • Hello. I forgot to copy it. Sorry. I am following this guide: https://developers.google.com/recaptcha/docs/invisible#programmatic_execute 2. example – jor Mar 07 '18 at 18:37
  • Ok, do you have an `onSubmit = function(token) {}` setup somewhere? – IncredibleHat Mar 07 '18 at 18:38
  • No. Thats what I am missing and I have no idea where to put this :( – jor Mar 07 '18 at 18:40
  • Ok, let me write up an example which should* work going on what you have so far. – IncredibleHat Mar 07 '18 at 18:41
  • Dude you are a hero! – jor Mar 07 '18 at 18:41

1 Answers1

4

You are missing the onSubmit() callback function.

To rearrange your js to utilize the function, this would be your new js block:

<script>
// this block must be defined before api.js is included
function onSubmit(token) {
    var fields = $('#contact-form').serializeArray();             // get your form data
        fields.push({name: "g-recaptcha-response", value: token});// add token to post
    $.ajax({
        type: "POST",
        url: "assets/php/contact.php",
        data: fields,
        dataType: 'json',
        success: function(response) {
            if(response.status) {
                $('#contact-form input').val('');
                $('#contact-form textarea').val('');
            }
            $('#response').empty().html(response.html);
        }
    });
    grecaptcha.reset();// to reset their widget for any other tries
}
</script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script>
// this block can be defined anywhere
$(function() {
    $("#contact-submit").on('click',function() {

        // call grecaptcha.execute, which causes recaptcha to
        // do its thing and then calls onSubmit with the token 

        grecaptcha.execute();// does not return anything directly

        return false;
    });
});
</script>
IncredibleHat
  • 4,000
  • 4
  • 15
  • 27
  • I now have the error that onload is not a function. I added $( in front of the first function and ); at the end. Still onload is not a function. Any ideas? – jor Mar 07 '18 at 18:54
  • after nice formatting I could get rid of the error. But now I have this one: ReCAPTCHA couldn't find user-provided function: onSubmit – jor Mar 07 '18 at 18:56
  • I realized you have these in .js files ... but the order does matter unfortunately. The function onSubmit, needs to exist in the page before the google js is called in (since its doing its thing when it loads). It looks for that defined function. – IncredibleHat Mar 07 '18 at 19:01
  • I added the first script function for testing in the header before the recaptcha js. Now oddly things are going on. Sometimes when I press the button nothing is happening. Sometimes it opens the 'Select images' dialog (yay progress! :) ) but he doesn't let me click on verify? – jor Mar 07 '18 at 19:09
  • Sometimes it pops up (thinking you are a bot from hitting it so often). Sometimes not. Sometimes it just passes on without bothering to check as it assumes you are human. If its not letting you click in their widget, I'm not sure how to solve that (could be a z-index issue?). But that goes off in a different direction/issue ;) – IncredibleHat Mar 07 '18 at 19:10
  • Im working things out. As soon as it works I'll reply! A huge thank you already! – jor Mar 07 '18 at 19:16
  • The addition of `e.preventDefault();` (which is a way to halt the basic form submit process, since you are sending the form via ajax) ... might conflict there. Removing that line won't hurt, as you cover halting the submit with `return false;`. Is there more going on in your `$("#contact-submit").on('click',function() ` than you had in your question code? – IncredibleHat Mar 07 '18 at 19:43
  • From your code you provided, you were hitting contact.php expecting json back. However in your contact.php you are simply echo'ing out strings. I don't know how validation would have worked that way, but you didn't show much of your contact.php. I can only guess you have a json_encode somewhere in there and not basic echos. – IncredibleHat Mar 07 '18 at 19:53
  • Yes you are right. For a better structure I replaced my alerts boxes by simply echo's. Here is what a check look likes (name): // Check name if(!$this->name) { $this->response_html .= '
    × Error! Please enter your name.
    '; $this->response_status = 0; }
    – jor Mar 07 '18 at 19:55
  • Sorry for the delay. I was copy/pasting the code here into a test app on my server. Then realized my google key wasn't setup for invisible, so I had to setup a new site for that. And then I did some basic tests (no validation of inputs, just json return of all incoming $_POST vars)... and the basics are working here. No idea what the issue could be. – IncredibleHat Mar 07 '18 at 20:29
  • My test example: http://bytejunkies.com/test/653.php Utilizes the code provided above, and your form html (my google key though). Only a couple minor debug output changes since I'm not actually validating the post vars (just echoing out what would have gone into contact.php). – IncredibleHat Mar 07 '18 at 20:40
  • You are a legend! Thank you! It is working for me as well. I cant thank you enough!! – jor Mar 07 '18 at 20:44