Implementing Google reCAPTCHA in ASP.NET MVC

Sheonarayan
Posted by in ASP.NET MVC category on for Advance level | Points: 250 | Views : 3678 red flag
Rating: 5 out of 5  
 1 vote(s)

In this article, we shall learn how to implement Google reCAPTCHA in ASP.NET MVC. reCAPTCHA is a free service by Google that protects a site from spam and abuse.
Recommendation
Read Different ways of hosting ASP.NET Web API before this article.

Introduction

Spam and site abuses are very frequently faced problems by webmasters or site owners. Generally this is done using automated robots that imitate the action of a human and keep submitting spam posts to the websites.

Google reCAPTCAH comes as an rescue for above problem. It is a free service provided by Google that protects a site from spam and abuse.

Where to start Google reCAPTCHA implementation?

To start implementing Google reCAPTCHA, first we need to register ourselves to Google. Go to the home page of Google reCAPTCHA (you must be logged in to Google account) and click on Get reCAPTCHA button that will take us to a web page that looks like this. 


After filling in all the details like a Label (like an account name) and then our domains for which we want to implement Google reCAPTCHA, click on  Register button that takes us to the page that looks like below.



Above page gives us Site key, Secret key and other information that is needed to implement reCAPTCHA to our website. Both keys are important to us.

To read Google reCAPTCHA documentation, go to https://developers.google.com/recaptcha/.

Implementing Google reCAPTCHA in ASP.NET MVC

For this article, I have created a Login page in ASP.NET MVC where we will implement Google reCAPTCH. Create a Login view page that looks like this.


Below is the code snippet to create above page.

@{
    ViewBag.Title = "Google reCaptcha";
}

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

<h2>Google reCaptcha</h2>
@using (Html.BeginForm("GoogleReCaptcha", "Home", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <h4>Please login - Google reCaptcha test</h4>
    <hr />

    <div class="form-group">
        <label class="col-md-2 control-label">Username: </label>
        <div class="col-md-10">
            <input type="text" placeholder="Username" name="UserName" class="form-control" />
        </div>
    </div>
    <div class="form-group">
        <label class="col-md-2 control-label">Password</label>
        <div class="col-md-10">
            <input type="password" placeholder="Password" name="Password" class="form-control" />
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <div class="checkbox">
                <label><input type="checkbox" name="RememberMe" />Remember me</label>
            </div>
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <div class="g-recaptcha" data-sitekey="6LedEiITAAAAAIJojg1rb4H7_HwL0QJGXD1KLqq-"></div>
            <span class="text-danger">@ViewBag.CaptchaErrorMessage </span>
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Log in" class="btn btn-default" />
        </div>
    </div>
}
Notice the italic codes that is important and related with Google reCAPTCHA. First we have referred the .js file at the top of the code snippet and then written the div tag with class and data-sitekey attribute that will render the Google reCAPTCHA on the page.

Create action methods for Google reCAPTCHA in ASP.NET MVC

We need two action methods in our controller, first is for HttpGet and another is for HttpPost (as we normally do in other asp.net view that has HTML form).

The first GoogleReCaptcha() method simply returns the view that contains the above code snippet.


using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Web.Mvc;

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult GoogleReCaptcha()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult GoogleReCaptcha(FormCollection form)
        {
            string urlToPost = "https://www.google.com/recaptcha/api/siteverify";
            string secretKey = "secret-key-from-2nd-image-above"; // change this
            string gRecaptchaResponse = form["g-recaptcha-response"];

            var postData = "secret=" + secretKey + "&response=" + gRecaptchaResponse;

            // send post data
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlToPost);
            request.Method = "POST";
            request.ContentLength = postData.Length;
            request.ContentType = "application/x-www-form-urlencoded";

            using (var streamWriter = new StreamWriter(request.GetRequestStream()))
            {
                streamWriter.Write(postData);
            }

            // receive the response now
            string result = string.Empty;
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (var reader = new StreamReader(response.GetResponseStream()))
                {
                    result = reader.ReadToEnd();
                }
            }

            // validate the response from Google reCaptcha
            var captChaesponse = JsonConvert.DeserializeObject<reCaptchaResponse>(result);
            if (!captChaesponse.Success)
            {
                ViewBag.CaptchaErrorMessage = "Sorry, please validate the reCAPTCHA";
                return View();
            }

            // go ahead and write code to validate username password against database


            return View();
        }

        private class reCaptchaResponse
        {
            [JsonProperty("success")]
            public bool Success { get; set; }

            [JsonProperty("challenge_ts")]
            public string ValidatedDateTime { get; set; }

            [JsonProperty("hostname")]
            public string HostName { get; set; }

            [JsonProperty("error-codes")]
            public List<string> ErrorCodes { get; set; }
        }
    }
}

In the second action method executes when the Log In button is clicked and this method does following.

  • We create few string variable to hold the url, secretKey, captcha response from the view (g-recaptcha-response - when the captcha is able to successfully validate the end user, some encrypted data is received from the google through this field, read the documentation to know about this) etc.

  • We have created the WebRequest on the URL provided.

  • Set the necessary values like Method, ContentType etc and posted the data to the url.

  • After that we have received the response using HttpWebResponse 

  • As this response is in JSON format we have DeSerialized it into a class named reCaptchaResponse.

  • If the response is coming as false, then we are writing the error message to the ViewBag and returning the View.

  • Otherwise this user is good and go ahead with the database validation for this user and do our work in the code.


Once all the code is setup, its time to run the application and test it.

Note that if we are running this page in the development environment, a message below the reCAPTCHA checkbox appears notifying about localhost otherwise if we are testing it live on the domain we have entered in the 1st screen shot above, it should work perfectly.

Conclusion

Spam and site abuses are major problems however service like this that too free helps Webmaster combating these problems and becoming safe. These services also helps us in keeping our site neat and clean for the real user.

Hope this article was informative and useful, do share your feedback or comment below. Thanks for reading this article.

Reference

  • https://www.google.com/recaptcha/admin
  • https://developers.google.com/recaptcha/
Page copy protected against web site content infringement by Copyscape

About the Author

Sheonarayan
Full Name: Sheo Narayan
Member Level: HonoraryPlatinum
Member Status: Administrator
Member Since: 7/8/2008 6:32:14 PM
Country: India
Regards, Sheo Narayan http://www.dotnetfunda.com
http://www.snarayan.com
Ex-Microsoft MVP, Author, Writer, Mentor & architecting applications since year 2001. Connect me on http://www.facebook.com/sheo.narayan | https://twitter.com/sheonarayan | http://www.linkedin.com/in/sheonarayan

Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)