0

I am using reCaptcha v2 in a form for my contact page. After sending the form all the content was sent to email including the G-recaptcha-response. How can I exclude it using jquery in client - side.

This is the setup:

<script src="https://www.google.com/recaptcha/api.js" async defer></script>
 <form method="post" name="frmcontact" id="frmcontact" action="/mail/contact">
    <table width="100%" cellspacing="5">
        <tr>
        <td><div class="spancontacttitle">Full Name:</div>
          <div class="spancontact">
            <input type="text" class="contact" name="fullname" id="fullname" value="{{post.fullname}}" />
        </div></td>
        </tr>
        <tr>
          <td><div class="spancontacttitle">Email:</div>
            <div class="spancontact relative">
            <input type="text" class="contact" name="email_address" id="email_address" value="{{post.email_address}}" />
          </div></td>
        </tr>
        <tr>
          <td><span class="spancontacttitle">Your comments:</span>
          <div class="spancontact"><textarea class="textareainquiry" name="comments" id="comments">{{post.comments}}</textarea></div></td>
        </tr>
        <tr>
            <td>
             <div class="g-recaptcha" data-sitekey="{{site['recaptcha-public-key']}}" data-callback="recaptchaCallback"></div>
             <input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha" id="hiddenRecaptcha">
            </td>
        </tr>

        <tr>
          <td><input type="submit" class="submitinquiry" name="sbmt" id="sbmt" value="Send" /></td>
        </tr>
    </table>

</form>

<script type="text/javascript">

$(document).ready(function(){

    function recaptchaCallback() {
        $('#hiddenRecaptcha').valid();
    };

   $("#frmcontact").validate({

    debug: true,
    ignore: ".ignore",
    submitHandler: function() {
       document.frmcontact.submit(); return true;
    },

    rules: {
        fullname: {
            required: true
        },
        email_address: {
            required: true,
            email: true
        },
        hiddenRecaptcha: {
            required: function () {
                if(grecaptcha.getResponse() == '') {
                    return true;
                } else {
                    return false;
                }
            }
        }
    },

    messages: {
        fullname: "This field must not be empty.",
        email_address: "Please provide a valid email address.",
        hiddenRecaptcha: "Error reCAPTCHA"
    }

});

});
</script>

What I have tried is disabling the hidden input upon clicking and verifying the reCaptcha:

hiddenRecaptcha: {
                required: function () {
                    if(grecaptcha.getResponse() == '') {
                        $('#hiddenRecaptcha').prop('disabled',false);
                        return true;
                    } else {
                        $('#hiddenRecaptcha').prop('disabled',true);
                        return false;
                    }
                }
            }

But, still, the form is sending the reCaptcha response. What I am missing here?

Maistrenko Vitalii
  • 944
  • 1
  • 7
  • 14
c.k
  • 1,045
  • 1
  • 14
  • 30
  • I'm assuming you need the reCaptcha to validate the form? So if you move it outside the `
    ` then the user could just bypass it. I suspect it would be easier to add an explicit exclusion in your server code that sends the email.
    – freedomn-m Mar 12 '18 at 09:26
  • Well, the problem, if I will move it outside the form, is I could not validate if the user clicked the reCaptcha button. Is there any way to validate the reCaptcha when it is outside the form just by jquery? – c.k Mar 12 '18 at 09:47
  • 1
    You can check easily enough by providing a `.submit()` handler. But would be too easy to bypass by the user - hence the recommendation to make it server-side. – freedomn-m Mar 12 '18 at 09:51

1 Answers1

0

Your recaptcha will be useless without passing the g-recaptcha-response to the server for validation, so think about solving it on server side. But if you still want a client solution without changing your markup, here is possible way:

$(function() {
  $("#frmcontact").submit(function(ev){
    ev.preventDefault();

    var arr = $(this).serializeArray();
    //concole.log(arr);
    //be sure that g-recaptcha-response is not there

    var form = document.createElement("form");
    form.setAttribute("method", "post");
    form.setAttribute("action", "/mail/contact");

    $.each(arr, function(k, v) {
      var newField = document.createElement("input");
      newField.setAttribute("type", "hidden");
      newField.setAttribute("name", v["name"]);
      newField.setAttribute("value", v["value"]);

      form.appendChild(newField);
    });

    document.body.appendChild(form);
    form.submit();
  });
});

The idea is to prevent original form from submitting, then to create another form invisible for user, add all required data and submit it. This is also described here.

Alex Yokisama
  • 726
  • 5
  • 8