157

I have a simple contact form in aspx. I want to validate the reCaptcha (client-side) before submitting the form. Please help.

Sample code:

    <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default2.aspx.vb" Inherits="Default2" %>
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Test Form</title>
        <link rel="stylesheet" href="//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css">
        <script src="//code.jquery.com/jquery-1.10.2.js"></script>
        <script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
        <link rel="stylesheet" href="/resources/demos/style.css">
        <script src="https://www.google.com/recaptcha/api.js" async defer></script>
        <script>
            $("#cmdSubmit").click(function () {
                //need to validate the captcha
            });
        </script> 
    </head>
    <body>
        <form id="form1" runat="server">
            <label class="clsLabe">First Name<sup>*</sup></label><br />
            <input type="text" id="txtFName" name="txtFName" class="clsInput" /><br />
            <div class="g-recaptcha" data-sitekey="my_key"></div>
            <img id="cmdSubmit" src="SubmitBtn.png" alt="Submit Form" style="cursor:pointer;" />
        </form>
    </body>
    </html>

I want to validate the captcha on cmdSubmit click.

Please help.

Mahatma Aladdin
  • 2,027
  • 3
  • 17
  • 31
  • 2
    what have you done so far? need more info, the question is too vague. – Zaki Jan 12 '15 at 13:04
  • 1
    If you are not sending a post request to google via server side validation you may as well not even include a captcha. The client side validations suggested below will be passed by bots. – Virge Assault Jul 09 '18 at 15:55
  • Validate captcha is clicked clientside > do something > validate recaptcha data server side > do something. – JPB Jul 12 '18 at 14:17
  • Don't. Verifying captchas client-side is defeating its very purpose. So are you planning to throw your secret key out the window? – Divins Mathew Jan 26 '21 at 18:15

16 Answers16

133

This Client side verification of reCaptcha - the following worked for me :

if reCaptcha is not validated on client side grecaptcha.getResponse(); returns null, else is returns a value other than null.

Javascript Code:

var response = grecaptcha.getResponse();

if(response.length == 0)
    //reCaptcha not verified

else
    //reCaptch verified
Rahul Gupta
  • 9,775
  • 7
  • 56
  • 69
Palak Taneja
  • 1,983
  • 3
  • 13
  • 12
  • 158
    This is incorrect. The Captcha has NOT been verified by JS, you need to submit the response, along with your site key and secret key, to Google's servers from your back end code in order to determine if the Captcha was successfully answered. This answer is dangerously incorrect. – Sean Kendle Jan 30 '17 at 21:16
  • 12
    Quote: When a reCAPTCHA is solved by end user, a new field (g-recaptcha-response) will be populated in HTML. https://developers.google.com/recaptcha/docs/verify – CoalaWeb Apr 25 '17 at 15:53
  • 8
    But that's not all @CoalaWeb ! Quote: After you get the response token, **you need to verify it** with reCAPTCHA using the following API to ensure the token is valid. [https://developers.google.com/recaptcha/docs/verify](https://developers.google.com/recaptcha/docs/verify) – Dylan Smith Oct 19 '17 at 20:39
  • It would be nice if there was a way to do some sort of "lite" validation on the client before sending to the server for real validation. That way you don't bog down your server with TONS of spam bots sending bad reCaptcha answers. That's what led me to this question. – evolross Nov 01 '17 at 18:20
  • 1
    Those bots could easily be adapted to trick the client-side verification though – Finlay Roelofs Nov 03 '17 at 13:05
  • 26
    To those saying the answer is not correct, did you even read the question? The question and answer both clearly specify client-side - the obvious intention is to check that the captcha was actually filled in client-side *before* sending a post request to the server for further validation.. – rococo Jan 21 '18 at 20:50
  • Ya this answer is actually same like above. The things is you get the response by accessing the key from grecaptcha object – Faris Rayhan Mar 05 '18 at 04:42
  • 1
    @SeanKendle you misunderstood the question. when your user submits unfinished/bad captcha you want to let him know before submitting the form and redirecting him away from the site. this is a fully valid scenario – user151496 Jun 19 '18 at 14:03
  • 1
    Fair, but it's very important to make some mention of the back end also validating against Google's servers. I don't want someone to come here, think that Recaptcha is a client-side-only solution, and neglect to check the answer against Google's servers. – Sean Kendle Jun 19 '18 at 15:12
  • @SeanKendle Is it always a compulsion to use Server side coding for recaptcha verification. Can I know on the client side if the Recaptcha response is a success ? – Abhishek Nov 02 '18 at 13:54
  • 4
    You can only know if the user has actually filled it out on the client side. The value of 'g-recaptcha-response' will be filled out, but that needs to be sent to Google for them to check if the response is valid or not. For example, with the image matching, you could click anything or nothing, and click submit. That's not correct, but the value of 'g-recaptcha-response' is filled out. You could use AJAX to verify it, but be sure to keep your secret key in the server side code. Short answer is the server has to check if it's valid, whether you do so with AJAX or with a full form post. – Sean Kendle Nov 02 '18 at 20:31
  • 1
    why does the validation need to be done server side? – Mike W Dec 02 '19 at 00:31
  • Instead of bothering with two stages of validation and Ajax calls, the simplest way would be to combine both validations [as per this article](https://www.freakyjolly.com/add-recaptcha-v2-and-form-validation-using-custom-jquery/) – clayRay Mar 31 '20 at 03:38
  • Do more with server side validation – Kaushik shrimali May 06 '20 at 13:28
  • @MikeW Validation must be done client side because you can never trust a web client; it is out of your control and a malicious user may have altered the data. – Matthew May 17 '20 at 23:32
  • This is incorrect. You still need to verify the response token. – themissionmars Jun 20 '22 at 12:52
65

Use this to validate google captcha with simple javascript.

This code at the html body:

<div class="g-recaptcha" id="rcaptcha" style="margin-left: 90px;" data-sitekey="my_key"></div>
<span id="captcha" style="margin-left:100px;color:red" />

This code put at head section on call get_action(this) method form button:

function get_action(form) 
{
    var v = grecaptcha.getResponse();
    if(v.length == 0)
    {
        document.getElementById('captcha').innerHTML="You can't leave Captcha Code empty";
        return false;
    }
    else
    {
        document.getElementById('captcha').innerHTML="Captcha completed";
        return true; 
    }
}
Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
Pravin Sharma
  • 1,160
  • 1
  • 8
  • 20
  • this code just above the span tag in body section – Pravin Sharma Feb 19 '15 at 14:01
  • 2
    I think this is the better solution. This way you can handle the validation of the response in your form submit handler. This seems more logical than trying to handle it on the captcha callback. I guess it depends if your validating on the fly or at submit. – Lightbulb1 Apr 22 '15 at 11:00
  • 4
    You should use `===` and `!==`; no reason not to. – slikts Aug 29 '15 at 17:53
  • I notice there is a textarea rendered. So, you could just use `document.getElementById('g-recaptcha-response').value=='') document.getElementById('captcha').innerHTML="You can't leave Captcha Code empty";` – Junior Mayhé Sep 23 '15 at 01:07
  • This doesn't for for multilingual support. – Vyacheslav Dec 13 '15 at 10:22
  • 32
    This solution is wrong. I think when you get response, you have to send parameter(response + secretkey + ClientIp) to the google for the validation. After validation. Google returns us success or fail. in your example, you dont use the second step. can you explain me: Where is your private key. When will you use? – Mahmut EFE Sep 02 '16 at 11:23
  • I am not understanding the second line, there is an span tag opening but never closing? ?? – Michael Fever Sep 13 '16 at 17:20
  • 4
    Mahmut is correct, this answer is dangerously wrong and incomplete. – Sean Kendle Jan 30 '17 at 21:13
  • @MichaelFever - It's a self-closing span tag, hence the /> at the end. It's invalid HTML, only valid in XML. – Sean Kendle Jan 30 '17 at 21:19
37

If you render the Recaptcha on a callback

<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>

using an empty DIV as a placeholder

<div id='html_element'></div>

then you can specify an optional function call on a successful CAPTCHA response

var onloadCallback = function() {
    grecaptcha.render('html_element', {
      'sitekey' : 'your_site_key',
      'callback' : correctCaptcha
    });
  };

The recaptcha response will then be sent to the 'correctCaptcha' function.

var correctCaptcha = function(response) {
    alert(response);
};

All of this was from the Google API notes :

Google Recaptcha v2 API Notes

I'm a bit unsure why you would want to do this. Normally you would send the g-recaptcha-response field along with your Private key to safely validate server-side. Unless you wanted to disable the submit button until the recaptcha was sucessful or such - in which case the above should work.

Hope this helps.

Paul

Rafa Viotti
  • 9,998
  • 4
  • 42
  • 62
pphillips001
  • 405
  • 3
  • 4
33

Simplified Paul's answer:

Source:

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

HTML:

<div class="g-recaptcha" data-sitekey="YOUR_KEY" data-callback="correctCaptcha"></div>

JS:

var correctCaptcha = function(response) {
        alert(response);
    };
Manuel Azar
  • 853
  • 2
  • 14
  • 24
  • 15
    Like many of the other wrong solutions, you're just getting the token here. You haven't *validated* it until you send it to Google with your secret key. – evolross Nov 01 '17 at 18:18
  • This somehow causing problem in my element. Webpack can not compiled it self if we use data-callback inside the element – Faris Rayhan Mar 05 '18 at 06:50
  • 2
    This should be the accepted answer as it doesn't require overwriting the render function. As for validation purely in JS, I doubt that is possible as it would require placing the secret key into the JS and thus allowing everyone to get their hands all over it. – Askerman Mar 06 '18 at 11:23
9

I used HarveyEV's solution but misread it and did it with jQuery validate instead of Bootstrap validator.

  <script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"></script>
  <script>
    $("#contactForm").validate({
      submitHandler: function (form) {
        var response = grecaptcha.getResponse();
        //recaptcha failed validation
        if (response.length == 0) {
          $('#recaptcha-error').show();
          return false;
        }
          //recaptcha passed validation
        else {
          $('#recaptcha-error').hide();
          return true;
        }
      }
    });
  </script>
imjosh
  • 4,734
  • 1
  • 19
  • 22
7

I thought all of them were great but I had troubles actually getting them to work with javascript and c#. Here is what I did. Hope it helps someone else.

//put this at the top of the page
<script src="https://www.google.com/recaptcha/api.js"></script>

//put this under the script tag
<script>
var isCaptchaValid = false;
function doCaptchaValidate(source, args) {
    args.IsValid = isCaptchaValid;
}
var verifyCallback = function (response) {
    isCaptchaValid = true;
};
</script>

//retrieved from google and added callback
<div class="g-recaptcha" data-sitekey="sitekey" data-callback="verifyCallback">

//created a custom validator and added error message and ClientValidationFucntion
<asp:CustomValidator runat="server" ID="CustomValidator1" ValidationGroup="Initial" ErrorMessage="Captcha Required" ClientValidationFunction="doCaptchaValidate"/>
BV2005
  • 147
  • 1
  • 9
4

you can render your recaptcha using following code

<div id="recapchaWidget" class="g-recaptcha"></div>

<script type="text/javascript">
   var widId = "";
   var onloadCallback = function ()
   {
    widId = grecaptcha.render('recapchaWidget', {
    'sitekey':'Your Site Key'
            });
   };
 </script>

 <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>

Then you can validate your recaptcha by using "IsRecapchaValid()" method as follows.

 <script type="text/javascript">
     function IsRecapchaValid()
      {
      var res = grecaptcha.getResponse(widId);
      if (res == "" || res == undefined || res.length == 0)
         {
          return false;
         }
       return true;
      }
 </script>
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Tabish Usman
  • 3,110
  • 2
  • 17
  • 15
4

Unfortunately, there's no way to validate the captcha on the client-side only (web browser), because the nature of captcha itself requires at least two actors (sides) to complete the process. The client-side - asks a human to solve some puzzle, math equitation, text recognition, and the response is being encoded by an algorithm alongside with some metadata like captcha solving timestamp, pseudo-random challenge code. Once the client-side submits the form with a captcha response code, the server-side needs to validate this captcha response code with a predefined set of rules, ie. if captcha solved within 5 min period, if the client's IP addresses are the same and so on. This a very general description, how captchas works, every single implementation (like Google's ReCaptcha, some basic math equitation solving self-made captchas), but the only one thing is common - client-side (web browser) captures users' response and server-side (webserver) validates this response in order to know if the form submission was made by a human or a robot.

NB. The client (web browser) has an option to disable the execution of JavaScript code, which means that the proposed solutions are completely useless.

vchyzhevskyi
  • 753
  • 1
  • 11
  • 20
2

Source Link

enter image description here

You can simply check on client side using grecaptcha.getResponse() method

          var rcres = grecaptcha.getResponse();
          if(rcres.length){
            grecaptcha.reset();
            showHideMsg("Form Submitted!","success");
          }else{
            showHideMsg("Please verify reCAPTCHA","error");
          }
Code Spy
  • 9,626
  • 4
  • 66
  • 46
2

Here's how we were able to validate the RECAPTCHA using .NET:

FRONT-END

<div id="rcaptcha" class="g-recaptcha" data-sitekey="[YOUR-KEY-GOES-HERE]" data-callback="onFepCaptchaSubmit"></div>

BACK-END:

    public static bool IsCaptchaValid(HttpRequestBase requestBase)
    {
        var recaptchaResponse = requestBase.Form["g-recaptcha-response"];
        if (string.IsNullOrEmpty(recaptchaResponse))
        {
            return false;
        }

        string postData = string.Format("secret={0}&response={1}&remoteip={2}", "[YOUR-KEY-GOES-HERE]", recaptchaResponse, requestBase.UserHostAddress);
        byte[] data = System.Text.Encoding.ASCII.GetBytes(postData);

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.google.com/recaptcha/api/siteverify");

        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = data.Length;

        using (var stream = request.GetRequestStream())
        {
            stream.Write(data, 0, data.Length);
        }

        var response = (HttpWebResponse)request.GetResponse();

        var responseString = "";

        using (var sr = new System.IO.StreamReader(response.GetResponseStream()))
        {
            responseString = sr.ReadToEnd();
        }

        return System.Text.RegularExpressions.Regex.IsMatch(responseString, "\"success\"(\\s*?):(\\s*?)true", System.Text.RegularExpressions.RegexOptions.Compiled);
    }

Call the above method within your Controller's POST action.

Colin
  • 1,758
  • 1
  • 19
  • 24
2

If you just want to avoid a trip to the server when the user hasn't even attempted the reCAPTCHA, put a validate function in the onsubmit action:

<form id="start_game" action="start-game" method="post" onsubmit="return validate_form();">

And then make that function something like this:

function validate_form() {

    const recaptcha_box_checked = (grecaptcha.getResponse()) ? true : false;

    if (recaptcha_box_checked) { 
        return true;
    }
    else {
        alert("You must check the 'I am not a robot' box before you can start a game!");
        return false;
    }
}

Now, the user could certainly subvert this, but your backend is going to check the g-recaptcha-response with a google server using your secret key. This just stops the user from having to go through another page or two when she simply forgets to check the box.

monist
  • 66
  • 5
1

I used Palek's solution inside a Bootstrap validator and it works. I'd have added a comment to his but I don'y have the rep;). Simplified version:

        $('#form').validator().on('submit', function (e) {
           var response = grecaptcha.getResponse();
           //recaptcha failed validation
           if(response.length == 0) {
               e.preventDefault();
               $('#recaptcha-error').show();
           }
           //recaptcha passed validation
           else {
               $('#recaptcha-error').hide();
           }
           if (e.isDefaultPrevented()) {
              return false;
           } else {
              return true;
           }
       });
HarveyEV
  • 101
  • 3
  • 8
0

You cannot validate alone with JS only. But if you want to check in the submit button that reCAPTCHA is validated or not that is user has clicked on reCAPTCHA then you can do that using below code.

 let recaptchVerified = false;
firebase.initializeApp(firebaseConfig);
firebase.auth().languageCode = 'en';
window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container',{
    'callback': function(response) {
        recaptchVerified = true;
        // reCAPTCHA solved, allow signInWithPhoneNumber.
        // ...
    },
    'expired-callback': function() {
        // Response expired. Ask user to solve reCAPTCHA again.
        // ...
    }
});

Here I have used a variable recaptchVerified where I make it initially false and when Recaptcha is validated then I make it true.

So I can use recaptchVerified variable when the user click on the submit button and check if he had verified the captcha or not.

Bhavesh Daswani
  • 707
  • 6
  • 11
0

Several comments and answers on this page mention that validating a CAPTCHA (Google reCAPTCHA or otherwise) on the client side is self-defeating, as this would require the server to send the solution to the CAPTCHA to the client - essentially giving the spammer exactly what he/she needs, without him/her having to solve the CAPTCHA.

This is not necessarily true. Instead of the server sending the solution to the client, the server can send a cryptographic hash of the solution to the client. Because cryptographic hash functions (such as SHA-256) are one-way functions, a spammer cannot easily reverse the hashed solution to come up with the solution. However, client-side code can easily verify if user solved the CAPTCHA correctly, by hashing the user's input and checking if it matches the hashed solution from the server.

For example, the solution to this CAPTCHA image is f753f. Instead of the server sending f753f to the client, the server sends SHA256('f753f'), which is 100e1bafe0235a0c268dc7d918802298de08a23293929607bc7ac8050fd1333c. A spammer cannot easily reverse the SHA256 function to find that the input that produced the value above is f753f. However, when the user attempts to solve the CAPTCHA, client-side code can easily take a SHA256 hash of the user's input, and check if the result is 100e1bafe0235a0c268dc7d918802298de08a23293929607bc7ac8050fd1333c. If so, then the user entered the correct solution.

Of course, when the form is submitted, the server should do its own independent validation, and not rely on the client for validation. However, performing the validation on the client side as well provides for a nice user experience, as the user can instantly see when they've solved the CAPTCHA correctly, without the client having to make a round trip to the server for each keypress.

Below is a simple implementation of this concept using HTML and Javascript:

<!doctype html>
<html>
    <body>
        <h1>Client-Side CAPTCHA Validation</h1>
        <table>
            <tr>
                <td>Enter CAPTCHA: <input id=txtCaptcha onkeyup='javascript:checkcaptcha()';></td>
                <td width=5%><div id=divCheckcaptcha></div></td>
                <td><img src=https://i.imgur.com/BpxtRrO.png></td>
            </tr>
        </table>
    </body>
    
    <script>
        var solutionhash='100e1bafe0235a0c268dc7d918802298de08a23293929607bc7ac8050fd1333c';
        
        function checkcaptcha() {
            var plaintextbytes=new TextEncoder("utf-8").encode(txtCaptcha.value);   
            window.crypto.subtle.digest('SHA-256', plaintextbytes)
            .then(function(result) {
                var resultUint8Array=new Uint8Array(result);
                var enteredcaptchahash=Uint8ArrayToHexString(resultUint8Array);             
                if(enteredcaptchahash==solutionhash) {
                    divCheckcaptcha.innerHTML='<font color=green>&#x2714;</font>';
                } else {
                    divCheckcaptcha.innerHTML='<font color=red>&#x2715;</font>';
                }       
            }); 

        }   
        
        function Uint8ArrayToHexString(ui8array) {
            var hexstring='', h;
            for(var i=0; i<ui8array.length; i++) {
                h=ui8array[i].toString(16);
                if(h.length==1) { h='0'+h; }
                hexstring+=h;
            }   

            var p=Math.pow(2, Math.ceil(Math.log2(hexstring.length)));
            hexstring=hexstring.padStart(p, '0');
            return hexstring;
        }

    </script>
</html>
mti2935
  • 11,465
  • 3
  • 29
  • 33
-1

if (typeof grecaptcha !== 'undefined' && $("#dvCaptcha").length > 0 && $("#dvCaptcha").html() == "") {
                dvcontainer = grecaptcha.render('dvCaptcha', {
                    'sitekey': ReCaptchSiteKey,
                    'expired-callback' :function (response){
                        recaptch.reset();
                        c_responce = null;
                    },
                    'callback': function (response) {
                        $("[id*=txtCaptcha]").val(c_responce);
                        $("[id*=rfvCaptcha]").hide();
                        c_responce = response;

                    }
                });
            }
            
            function callonanybuttonClick(){
             
                if (c_responce == null) {
                    $("[id*=txtCaptcha]").val("");
                    $("[id*=rfvCaptcha]").show();

                    return false;
                }
                else {
                    $("[id*=txtCaptcha]").val(c_responce);
                    $("[id*=rfvCaptcha]").hide();
                    return true;
                }
            
}
<div id="dvCaptcha" class="captchdiv"></div>
    <asp:TextBox ID="txtCaptcha" runat="server" Style="display: none" />
    <label id="rfvCaptcha" style="color:red;display:none;font-weight:normal;">Captcha validation is required.</label>

Captcha validation is required.

-2
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!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">
<head runat="server">
    <title></title>
    <script src='https://www.google.com/recaptcha/api.js'></script>
    <script type="text/javascript">
        function get_action() {
            var v = grecaptcha.getResponse();
            console.log("Resp" + v);
            if (v == '') {
                document.getElementById('captcha').innerHTML = "You can't leave Captcha Code empty";
                return false;
            }
            else {
                document.getElementById('captcha').innerHTML = "Captcha completed";
                return true;
            }
        }
    </script>
</head>
<body>
    <form id="form1" runat="server" onsubmit="return get_action();">
    <div>
    <div class="g-recaptcha" data-sitekey="6LeKyT8UAAAAAKXlohEII1NafSXGYPnpC_F0-RBS"></div>
    </div>
   <%-- <input type="submit" value="Button" />--%>
   <asp:Button ID="Button1" runat="server"
       Text="Button" />
    <div id="captcha"></div>
    </form>
</body>
</html>

It will work as expected.

Papun Sahoo
  • 407
  • 5
  • 13