Implementing reCAPTHCA

I wanted to outline some recent work I’ve done with the reCAPTCHA Google API. Although not too difficult to implement, I did struggle a little to find C# based server side examples on how to ultimately validate a CAPTCHA. To start us off however, what is reCAPTCHA?

reCAPTCHA is essentially a mechanism to protect your sites functionality from spam and other kinds of abusive activity. It’s free, which is a massive bonus, and as a cherry on top every solved CAPTCHA is used to annotate images and build on machine learning datasets. This data feeds into solving a myriad of problems, including improving maps and solving AI conundrums. The actual term is an acronym for Completely Automated Public Turing test to tell Computers and Humans Apart. For any history buffs, details on how this concept came about can be found here (in fact, there seems to be an interesting ‘origin of’ debate here):

Wiki CAPTCHA Documentation

And something a bit more fun:

To get started using reCAPTCHA, and for further information, you just need to visit the following link:

Google reCAPTCHA

Utilising reCAPTCHA version 2.0 seemed like the way to go for me and has a number of benefits. For example, it’s possible for this implementation to automatically confirm some requests as not being malicious in nature, without the need for a CAPTCHA to be solved. In addition, the CAPTCHAs themselves in version 2 are much nicer for a human to solve, relying on a party to pick out characteristics in an image, rather than trying to read ever more complex and convoluted character strings embedded in a given image. Image resolution (to pick out particular objects) is still a field whereby programs struggle somewhat, so this form of reCAPTCHA falls into a more secure bracket also.

Using reCAPTCHA

The basic process boils down to following these steps:

  • Go to the Google reCAPTCHA site and click on Get reCAPTCHA.
  • Sign in or sign up, do what you’ve got to do!
  • Register the domain where you want to embed reCAPTCHA. This will enable you to receive the relevant API keys to create and validate CAPTCHAs.
  • Add the relevant JavaScript to your page.
  • Embed the Site key in the page being served to the user (we’ll go over this below).
  • Use the Secret Key in your server side logic to validate the CAPTCHA response (based on user input). This is done by sending a request to the Google API siteverify address. Again, I’ll cover this below.
  • Get the response and see if the CAPTCHA has been solved correctly, simple as that.

First things first, you’ll want to safely note down your Site and Secret key for further use, these can be viewed again at any time by logging into the reCAPTCHA portal (where you signed up). So you’ve registered your domain and have the relevant keys, we now need to embed reCAPTCHA by adding the following element to the page you want to target:

<head>
...
    <!--Use async/defer as necessary if you desire-->
    <script src='https://www.google.com/recaptcha/api.js'></script>
...
</head>
<body>
    ...
    <!--The id attribute is not absolutely required, but I have listed it here as I make further use of (basically a style choice) for an jQuery AJAX call (could just use the class however)-->
    <div id="g-recaptcha-response" class="g-recaptcha" data-sitekey="YOUR_SITE_KEY_GOES_HERE"></div>
    ...
</body>

Be sure to drop the Site key you were provided with in the data-sitekey attribute, within the div outlined (and add the JavaScript reference listed to your page). Load up your page and you should see something akin to the following:

reCAPTCHA V2 Control.
reCAPTCHA V2 Control.

This is a super start. If you are doing a simple post on submit, you’ll be able to pull information out of the standard request object and use this server side. For me however, I wanted something incredibly lightweight so I went with the following jQuery AJAX call (I may tweak this in my personal implementation so treat this as not yet finalised, but it provides you with an idea of the structure nonetheless):


//Defines an outline (structure) for a javascript contact object
function Contact(name, email, message, recaptchaClientResponse) {
	this.Name = name
	this.Email = email;
	this.Message = message;
	this.RecaptchaClientResponse = recaptchaClientResponse;
}

...

//Submit Enquiry button click handler
$(".submit-enquiry").click(function (e) {

	//Hide the alert bar on every new request (TODO - More code required to tidy up classes on the alert div)
	$(".alert").hide();

	//Use ajax to call the service HandleEmailRequest method
	$.ajax({
		cache: false,
		async: true,
		type: "POST",
		dataType: "json",
		processData: false,
		data: JSON.stringify(
			{
				contactObj: new Contact
					(
						$("#NameTextBox").val(),
						$("#EmailTextBox").val(),
						$("#MessageTextArea").val(),
						$("#g-recaptcha-response").val()
					)
			}),
		url: "URL_TO_A_SERVICE.svc/HandleEmailRequest",
		contentType: "application/json;charset=utf-8",
		success: function (evt) {
			//Evaluate the response and add content to alert bar
			if (evt.SendEmailResult)
			{
				$(".alert").addClass("alert-success").html("<p>Message successfully sent!</p>").slideDown(1000);
			}
			else
			{
				$(".alert").addClass("alert-danger").html("<p>We couldn not send the message, sorry about that.</p>").slideDown(1000);
			}

			//Reset the recaptcha control after every request
			grecaptcha.reset();
		},
		error: function (evt) {
			//Add content to the alert bar to show the request failed
			$(".alert").addClass("alert-danger").html("<p>We could not send the message, sorry about that.</p>").slideDown(1000);

			//Reset the recaptcha control after every request
			grecaptcha.reset();
		}
	});
});

The first part of this code encapsulates the idea of a contact, in my case at least (i.e. a user leaving a message on the web page that will become an email). This is just an easy way for me to encapsulate details during the AJAX call. Using jQuery, I’ve attached a handler to the submit button on my page which, apart from a little UI manipulation (for an alert bar element), in essence just makes a call to a service (via the url parameter) using details that the client has provided, including information on the solved CAPTCHA. This is passed to the service using the data parameter; note the use of jQuery to get details of the CAPTCHA the user has completed ($(“#g-recaptcha-response”).val()). This is passed as JSON to the service. Once a request has been validated, the return value (a simple boolean in my case) is inspected and an alert is shown to the user before resetting the reCAPTCHA control (another spam control mechanism that I’ve added in for extra peace of mind). Lastly, for me, the use of JSON.stringify was absolutely key as I want to work with JSON data over the wire. More details can be found here:

JSON.stringify() Documentation

This is where it got a little trickier to proceed. On the reCAPTCHA documentation site, for version 2.0, I could only see examples for PHP:

reCAPTCHA Code Examples Available.
reCAPTCHA Code Examples Available.

So, what you’ll see next is the culmination of my digging around for a jQuery/AJAX/C# solution to this particular head-scratcher. Hopefully, it proves useful to anyone interested in going down this route.

Let’s get going! On the service side, you’ll need something like the following, to gather up the AJAX request:

/// <summary>
/// Represents a Contact (Potential Customer) contacting
/// the recipient with an enquiry.
/// </summary>
[DataContract]
public class Contact
{
	#region Automatic Properties (Data Members)

	/// <summary>
	/// The Contacts full name.
	/// </summary>
	[DataMember]
	public string Name { get; set; }

	/// <summary>
	/// The Contacts email address.
	/// </summary>
	[DataMember]
	public string Email { get; set; }

	/// <summary>
	/// The Contacts message to the recipient.
	/// </summary>
	[DataMember]
	public string Message { get; set; }

	/// <summary>
	/// A string that represents the clients reCAPTCHA
	/// (V2) response (passed along with other Contact
	/// information and processed before a message can be sent).
	/// </summary>
	[DataMember]
	public string RecaptchaClientResponse { get; set; }

	#endregion Automatic Properties (Data Members)
}

...

/// <summary>
/// Outlines the HandleEmailRequest method that is part of this service.
/// Consumes and returns a JSON format message (called from the client
/// with details that instantiate a Contact object). Method designed to 
/// process reCAPTCHA details and, on success, send an email to
/// the designated (recipient) email address. 
/// </summary>
/// <param name="contactObj">Contact details associated with the person requesting information.</param>
/// <returns></returns>
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
bool HandleEmailRequest(Contact contactObj);

...

/// <summary>
/// Public service method that attempts to send a
/// user message to the recipient as an email.
/// </summary>
/// <param name="contactObj">The Contact object constructed from JSON (passed from the client).</param>
/// <returns>A boolean that represents if this process was successful.</returns>
public bool HandleEmailRequest(Contact contactObj) => new EmailSender(contactObj).SendEmail();

I’ve given you a roll-up of an example Contact class (that is instantiated from the JSON automatically on call to the service), an example service interface definition and the outline of a service method (contained in a class implementing this interface). These of course are in separate files, but I’ve lined them up side-by-side to make it easier to absorb. In my case, the details are passed to and wrapped in an EmailSender class, the reCAPTCHA validation being called internally by the SendEmail method (as a private method called ValidateRecaptchaClientResponse):

/// <summary>
/// Private helper method that looks at the Contact object
/// associated with this EmailSender and attempts to verify
/// if the reCAPTCHA client response is valid (before attempting to
/// send an email message to the recipient). 
/// </summary>
/// <returns>A boolean that represents if reCAPTCHA validation succeeded or failed.</returns>
private bool ValidateRecaptchaClientResponse()
{
	//Online reference used as a basis for this solution: http://www.codeproject.com/Tips/851004/How-to-Validate-Recaptcha-V-Server-side
	try
	{
		//Make a web request to the reCAPTCHA siteverify (api) with the clients reCAPTCHA response. Utilise the Response Stream to attempt to resolve the JSON returned
		HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(string.Concat("https://www.google.com/recaptcha/api/siteverify?secret=YOUR_SITE_SECRET_KEY_GOES_HERE&response=", contactObj.RecaptchaClientResponse));

		using (WebResponse response = wr.GetResponse())
		{
			using (StreamReader sr = new StreamReader(response.GetResponseStream()))
			{
				//Use a JavaScriptSerializer to transpose the JSON Response (sr.ReadToEnd()) into a RecaptchaResponse object. Alter the 'Success' string of this object to a bool if possible
				bool success = false;
				bool.TryParse(new JavaScriptSerializer().Deserialize<RecaptcaResponse>(sr.ReadToEnd()).Success, out success);

				//Return a value that denotes if this reCAPTCHA request was a success or failure
				return success;
			}
		}
	}
	catch (Exception ex)
	{
		//Catch any exceptions and write them to the output window (better logging required in future). Return false at the end of this method, issue occurred
		System.Diagnostics.Debug.WriteLine($"An error occurred whilst validating the ReCaptcha user response. Type: { ex.GetType().Name } Error: { ex.Message }.");
	}

	//If we hit this portion of the code something definitely went wrong - Return false
	return false;
}

Lines fourteen and twenty two are of the most interest here. On line fourteen, you will be required to insert your site ‘Secret key’ into a request to the siteverify address we mentioned earlier. The response that needs to be appended to this string is equal to the reCAPTCHA information you gleaned from the client. You’ll notice that line twenty two makes use of a RecaptchaResponse type; which is basically an object wrapper used to contain information from the deserialised JSON response (as part of a reCAPTCHA check). This is outlined as follows:

/// <summary>
/// Represents an object (constructed from JSON)
/// that outlines a reCAPTCHA Response, and the pieces
/// of information returned from a verification check.
/// </summary>
public class RecaptcaResponse
{
	#region Automatic Properties

	/// <summary>
	/// The success status of the reCAPTHCA request.
	/// </summary>
	public string Success { get; set; }

	/// <summary>
	/// The Error Descriptions returned (Possibly to implement
	/// in the future).
	/// </summary>
	//public string ErrorDescription { get; set; }

	#endregion Automatic Properties
}

The actual JSON returned from the response stream takes the following form, so it is possible to extract error codes also if you desire (for me, I’m ripping a simple boolean out of this based on the success value):

{
  "success": true|false,
  "error-codes": [...]   // optional
}

On a very last note, cited in the code above but to reiterate, this link was invaluable:

Code Project reCAPTCHA Validation Example

That’s about it for a basic end to end sample.

The API documentation (and the steps listed on the reCAPTCHA site after registration) are pretty good, so you should be in safe enough hands:

reCAPTCHA API Documentation

Thanks all and take care until the next time.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.