Adding Google reCapthca v2 using ASP.Net

23 September 2016

Adding Google reCapthca v2 using ASP.Net

Google's reCaptcha system is very effective at preventing spam, but unlike other systems, does not require you to squint at a screen for ages to work out whether that wobbly circle is an o, O or a 0.  With Google's captcha system, all you have to do is click on the 'I am not a robot' checkbox. If someone tries too many times to fill your form in, or the system detects a suspicious response, then it will pop up a series of images and ask to you to identify which image contains pasta or an aeroplane for example. It's quite simple and clever in the way it works.

The way it works is quite straightforward: when you embed the reCaptcaha javascript tag, the captcha code inserts a hidden form field with a pre-generated string created by Google's servers, and then when the form is posted, you send back the contents of this field, plus a secret key to google's web service. The reCaptcha server then looks at the secret key and hidden field string and checks whether the string was generated by its own system using your site key, and if so, it returns a 'true' or if not it returns 'false'.  

Version 1 of the reCatpcha included sample code for ASP.net however the newer version does not, so I had to work out how to do this myself. Heres how I added reCaptcha v2 using ASP.net. The code below is written in C# and built using web forms, but it can easily be modified of MVC based applications:

STEP 1 - sign up for your secret key

To do this, go to https://www.google.com/recaptcha and click on the 'get recaptcha' button in the top right.

If you already have a google account, you can log in with this, or if you don't (and who doesn't have one?) then you'll have to register a google account.

Once done, you then add your website domain names to get 2 unique keys: a Site Key and a Secret Key. The site key is used in your code's script tag in your web form, and the secret key is used by your site to create a verification request to the reCaptcha web service.

 

STEP 2 Integrating the code in your form

Integrating the code into the front end web form is really easy. All you have to do is add 2 lines of code:

  1. paste the following into the <head> section of your page:

    <script src='https://www.google.com/recaptcha/api.js'></script>
  2. paste the following into the body of your html, where you want the captcaha button to appear:

    <div class="g-recaptcha" data-sitekey="[SITE KEY HERE]"></div>

 

STEP 3. Server Side Validation

When the form is generated in a browser, Google's recaptcha script adds a hidden field element called 'g-recaptcha-response'. To validate the form, you need to send an ajax call to google's web service with the contents of this field, and your secret key - this will return success:true if the response and key are valid, or otherwise will return success:false.

Here's the code for doing this. Note, this code uses Json.NET which is just used for a shortcut to parse JSON responses - in this case the reponse is serialised into the CaptchaResponse object but if you want to create a simple convertor yourself, it's not very hard to do that. The only slight complication is that If you want to use json.net, then you'll need to download the dll files from the newtonsoft site and copy then to the bin folder of your web application.

HTML code (contactform.aspx):

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="contactform.cs" Inherits="contactform" %>
<html>
<head runat="server">
<script src='https://www.google.com/recaptcha/api.js'></script>
</head>
<body>
<form runat="server">
Name: <asp:textbox id="txtName" runat="server" /><br />
Message: <asp:textbox id="txtMessage" runat="server"><br />
<div class="g-recaptcha" data-sitekey="[SITE KEY HERE]"></div>
<asp:literal id="litMessage" runat="server" />
<asp:button id="btnSend" runat="server" text="Send" />
<asp:literal id="litDebug" runat="server" />
</form>
</body>
</html>

C# code (contactform.cs):

using Newtonsoft.Json;
using System;
using System.IO;
using System.Net;

public partial class contactform:System.Web.UI.Page {

protected void Page_Load(object sender, EventArgs e) {
}

protected void btnSend_Click(object sender, EventArgs e) {

string reCaptchaSecret = "[SECRET KEY HERE]";
string reCaptchaRequest = "";

if (Request.Form["g-recaptcha-response"] != null) {reCaptchaRequest = Request.Form["g-recaptcha-response"].ToString();}

if (CheckReCaptcha(reCaptchaSecret, reCaptchaRequest)) {
// catpcha request is validated, do the form proccessing here...
string mName=txtName.Text;
string mMessage=txtMessage.Text;
// Add code here to save messages to database or send via email.
} else {
litMessage.Text = "Please confirm that you are not a robot.<br>";
}
}

public bool CheckReCaptcha(string captchaSecret, string captchaRequest) {
bool cValidated = false;

if (captchaRequest != null) {

string captchaURL = String.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", captchaSecret, captchaRequest);
HttpWebRequest wrq = (HttpWebRequest)WebRequest.Create(captchaURL);
wrq.ContentType = "application/json";
wrq.Method = "POST";
using (var streamWriter = new StreamWriter(wrq.GetRequestStream())) {

try {
var wrs = (HttpWebResponse)wrq.GetResponse();
using (var streamReader = new StreamReader(wrs.GetResponseStream())) {
var result = streamReader.ReadToEnd();
if (result != "") { CaptchaResponse capResp = JsonConvert.DeserializeObject<CaptchaResponse>(result);
cValidated = capResp.success;
}
}
} catch (WebException ex) {
if (ex.Status == WebExceptionStatus.ProtocolError) {
litDebug.Text = "ERROR : " + ex.Response.ToString() + "\r\n\r\nexception = " + ex.Message + "\r\n"; // debugging code
}
}
}
}
return cValidated;
}

public class CaptchaResponse {
public bool success { get; set; }
public string challenge_ts { get; set; }
public string hostname { get; set; }
public string errorCodes { get; set; }
}

}

 

Summary

Before adding this code to my website, I used to get about 20-30 spam messages per day. I installed this code about a week ago and to date I have not received a single spam submission.