Implementing Google's Invisible ReCaptcha In .NET

Implementing Google's Invisible ReCaptcha In .NET

If keeping bots away is your thing, then using Google's reCAPTCHA is a must. And while it can be tedious to click on 20 images of cars in order to verify that I'm human, it will keep your database clean from spam. Thanks to the new Invisible reCAPTCHA users won't know that there is a security measure in place until after they perform some action on your website. Which is good from a UX standpoint as seeing a reCAPTCHA field might deter some users from signing up. Sounds weird, but it's true.

Get your API keys

In order to use Google's reCAPTCHA widget you will need to register your domain and to get your own set of API keys, which you can get from the following URL. You will receive 2 tokens, one public and one secret. The public token is used in your client side script while the secret key will be used on the server side code to verify a users response.

Include the API script

You'll next up want to reference the reCAPTCHA API script on your page.


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

Note: In order to prevent race conditions from occurring with your scripts, ensure that your script tag is called after your callback method.
The script must be loaded using the HTTPS protocol and can be included from any point on the page without restriction.

Multiple ways to invoke

There are 3 ways to invoke the reCAPTCHA widget from your website. Note that the word "challenge" down below essentially means the widget.

1. Automatically bind the challenge to a button

This is the simplest and most straightforward way to implement the widget. You essentially include the library script onto your page and then add the following few attributes to an HTML button.

  • class="g-recaptcha"
  • data-sitekey
  • data-callback

<form id='demo-form' action="?" method="POST">
      <button class="g-recaptcha" data-sitekey="your public token goes here" data-callback='onSubmit'>Submit</button>
</form>

A few things to note. The button must be inside a form tag and must include the attributes listed. The data-callback attribute will be the JavaScript method that is to be called once a user has completed the challenge.

That is all that is required to begin using the Invisible reCAPTCHA, and submitting the button should render the following for first time users.

Implementing Google's Invisible ReCaptcha In .NET

Note: Once you solve the challenge the first time, you will no longer be presented with it going forward. Submitting the form will automatically call the callback method. Hense, its invisibility.

2.
Programmatically bind the challenge to a button

Next up is the more dynamic method. If you wish to bind the reCATPCHA programatically. Essentially, if you don't know which button will submit the request until after some action. This can be done by adding a few more parameters to the API script resource.

You'll need to specify the onload method to call when the page loads, and will need to set the render type to explicit.


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

Once the page has finished loading, you can then render the widget by calling the grecaptcha.render method.


<script type="text/javascript">
  var onloadCallback = function() {
    alert("grecaptcha is ready!");
    grecaptcha.render();
  };
</script>

3. Programmatically invoke the challenge

This is a good method to use if you have some type of validation in place and you wish to load the widget after that validation has been completed.

You'll first want to include the following div somewhere on your page and set the data-size attribute to "invisible".


<div class="g-recaptcha"
          data-sitekey="your_site_key"
          data-callback="onSubmit"
          data-size="invisible">
</div>

The reCAPTCHA can then be invoked through JavaScript using the grecaptcha.execute(); method.


<script type="text/javascript">
      grecaptcha.execute();
</script>

After successfully executing the widget, the submit callback method will be called.

Verifying the users response

The previous steps ensured that we displayed the reCAPTCHA challenge correctly, but it didn't actually show us whether the user passed or did not pass the challenge. This involves several steps of which we'll outline down below.

Capture response token from Google

Once the user solves or does not solve the reCAPTCHA challenge, the callback function that declared up above will get called.

The new reCAPTCHA offers several different ways to go about verifying the users response. But I'll be showing how to do it by sending a simple POST request to Google with the users response. Once the form is submitted, the reCAPTCHA will add the g-recaptcha-response POST parameter to your parameter list, which is an encrypted string that will only work once and that you must send to Google to verify.

You can use the following URL to verify any tokens that you may get through the widget.

URL: https://www.google.com/recaptcha/api/siteverify


private bool CheckCaptcha()
{
        string url = "https://www.google.com/recaptcha/api/siteverify";
        WebRequest request = WebRequest.Create(url);
        string postData = string.Format("secret={0}&response={1}&remoteip={2}", ConfigurationManager.AppSettings["CaptchaSecretKey"], Request["g-recaptcha-response"], Request.UserHostAddress);
        
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = postData.Length;

        StreamWriter writer = new StreamWriter(request.GetRequestStream());
        writer.Write(postData);
        writer.Close();

        StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream());
        string responseData = reader.ReadToEnd();
        
        JavaScriptSerializer jss = new JavaScriptSerializer();
        reCaptchaResponse cResponse = jss.Deserialize(responseData);
        return cResponse.success;
}

The response from Google should be in the following JSON format.


{
  "success": true|false,
  "challenge_ts": timestamp,  // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
  "hostname": string,         // the hostname of the site where the reCAPTCHA was solved
  "error-codes": [...]        // optional
}

We can deserialize our response to the following object, as success is the only real value that we will need to verify.


// define a new class to store our response, outside of the current class
public class reCaptchaResponse
{
    public bool success { get; set; }
}

Once the challenge is verified, you can then move forward which whichever logic you are implementing. The Invisible reCAPTCHA is definitely a step up in the right direction for user verification. The first time run can be time consuming, but then your user will never see it again, unless they clear their cookies of course.

Walter G. author of blog post
Walter Guevara is a Computer Scientist, software engineer, startup founder and previous mentor for a coding bootcamp. He has been creating software for the past 20 years.

Get the latest programming news directly in your inbox!

Have a question on this article?

You can leave me a question on this particular article (or any other really).

Ask a question

Community Comments

J
John David
7/10/2020 10:42:27 AM
nothing
P
Praveen
7/30/2021 11:01:50 AM
Send me this as a sample project

Add a comment