Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Google reCaptcha v2 with MVC5

0.00/5 (No votes)
9 Apr 2015 1  
Setting up Google reCaptcha version 2 with MVC5

Introduction

The main purpose of this tip is to show a way of using the new Google reCaptcha plugin with MVC5. I think it would cover MVC4 as well.

Background

I was working on a project which required reCaptcha and the nuget plugin which seems to be the most documented in the old version. I couldn't find much on the new plugin, so I thought I should show how I came up with a solution.

Using the Code

To start, I signed up to reCaptcha and acquired my public and secret key. I added these to the web.config file.

XML
<appSettings>
    <add key="RecaptchaPrivateKey" value="PRIVATEKEYHERE" />
    <add key="RecaptchaPublicKey" value="PUBLICKEYHERE" />
</appSettings>

I then set out to display the reCaptcha plugin using an HtmlHelper extension. I pulled the public key from the web.config and sent back the HTML string.

C#
public static class HtmlHelpers {

    public static IHtmlString reCaptcha(this HtmlHelper helper) {
        StringBuilder sb = new StringBuilder();
        string publickey = WebConfigurationManager.AppSettings["RecaptchaPublicKey"];
        sb.AppendLine("<script type=\"text/javascript\" 
        src='https://www.google.com/recaptcha/api.        js'></script>");
        sb.AppendLine("");
        sb.AppendLine("<div class=\"g-recaptcha\" 
        data-sitekey=\""+ publickey+"\"></div>");
        return MvcHtmlString.Create(sb.ToString()); 
    }
}

In the View, I wanted to display the reCaptcha I just used.

ASP.NET
<div class="editor-label">
    Are you a human?
</div>
<div class="editor-field">
    @Html.reCaptcha()
</div>
I then created a new class inheriting from ActionFilterAttribute so I could capture the response code, send the web request and add the response to the action parameters.
C#
public override void OnActionExecuting(ActionExecutingContext filterContext) {
 
    if (filterContext.RequestContext.HttpContext.Request["g-recaptcha-response"] != null) {
 
        string privatekey = WebConfigurationManager.AppSettings["RecaptchaPrivateKey"];
        string response = filterContext.RequestContext.HttpContext.Request["g-recaptcha-response"];
        filterContext.ActionParameters["CaptchaValid"] = Validate(response, privatekey); 
    } 
}

I built the Validate function which handles the request and the Json response using Newtonsoft.Json with a bespoke object for the request.

C#
public static bool Validate(string mainresponse, string privatekey) {
 
    try {
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create
        ("https://www.google.com/recaptcha/api/siteverify?secret=" + 
        privatekey + "&response=" + mainresponse);
 
        WebResponse response = req.GetResponse();
 
        using (StreamReader readStream = new StreamReader(response.GetResponseStream())) {
            string jsonResponse = readStream.ReadToEnd();
 
            JsonResponseObject jobj = JsonConvert.DeserializeObject<JsonResponseObject>(jsonResponse); 
 
            return jobj.success;
        }
    }
    catch (Exception) { 
        return false; 
    } 
}
public class JsonResponseObject {
    public bool success { get; set; }
    [JsonProperty("error-codes")]
    public List<string> errorcodes { get; set; }
}

Then, I add the RecaptchaFilter to the FilterConfig so the check for the capture is done on all ActionResults.

C#
filters.Add(new RecaptchaFilter());

Then, I just added the CaptchaValid parameter to my controller and set up my condition.

C#
public ActionResult MyController(MyModel model, bool CaptchaValid) {
 
    if (!CaptchaValid) {
        ModelState.AddModelError("reCaptcha", "Invalid reCaptcha");
        return View(model);
    }
    else {
        return View();
    } 
}

Points of Interest

When importing the correct usings for ActionFilterAttribute for the RecaptchaFilter, use using System.Web.Mvc;

NOT using System.Web.Http.Filters;

Remarks

The project included is a fully working example, provided a Private & Public key has been added to the web.config.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here