Tuesday, September 15, 2015

reCAPTCHA 2.0

The folks at Google have released a new version of their CAPTCHA product named reCAPTCHA.  They refer to the new version as the No CAPTCHA reCAPTCHA.  It's fairly easy to implement even in an ASP.NET MVC web application as I'll show below.

First, go here and sign up.  You input the domains at which your site will be hosted.  LocalHost always "just works" so don't worry about development.  However, if you're testing at a different domain than production, be sure to put both in there.  You'll be given two keys.  The "site" key and the "secret" key.

Implementing the CAPTCHA is a two part process.

First Part - Display the CAPTCHA control for the user to "solve"

Add this to the top of your view:

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

Then add this where you want the CAPTCHA box to appear:

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

That's all.

Second Part - Verify that the CAPTCHA was solved correctly

This is the more tricky of the two parts.

Once the user submits the form, reCAPTCHA is going to insert an additional form field named g-recaptcha-response into the form.  This will look like gobbly-gook.  This response along with the secret key needs to be sent to a Google web service.  The web service will return a JSON object that contains a success attribute.  If the success attribute is true, the user solved the CAPTCHA and you can safely assume that he or she is not a bot.

First, in your controller, add a data contract that you can deserialize the JSON response into:

<System.Runtime.Serialization.DataContract>
Private Class GoogleResults
    <System.Runtime.Serialization.DataMember(Name:="success")>
    Public Success As Boolean
End Class

Next, in your post action method within the controller use the following code:

Dim RecaptchaResponse As String = Request("g-recaptcha-response")

Dim MyClient As System.Net.WebClient = New System.Net.WebClient

Dim Reply As String = _
            MyClient.DownloadString(String.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", "SECRET-KEY-GOES-HERE", RecaptchaResponse))

Dim MySerializer As New System.Runtime.Serialization.Json.DataContractJsonSerializer(GetType(GoogleResults))

Dim MyStream = New System.IO.MemoryStream(Encoding.Unicode.GetBytes(Reply))

Dim Results As GoogleResults = CType(MySerializer.ReadObject(MyStream), GoogleResults)

If Not Results.Success Then
    ModelState.AddModelError("", "You must verify that you are not a robot.")
End If

If Not ModelState.IsValid Then
    Return View(model)
End If


No comments:

Post a Comment