Validating Recaptcha 2 (No CAPTCHA reCAPTCHA) in ASP.NET's server side Validating Recaptcha 2 (No CAPTCHA reCAPTCHA) in ASP.NET's server side asp.net asp.net

Validating Recaptcha 2 (No CAPTCHA reCAPTCHA) in ASP.NET's server side


After reading many resources, I ended up with writing this class to handle the validation of the new ReCaptcha :

As mentioned Here : When a reCAPTCHA is solved by end user, a new field (g-recaptcha-response) will be populated in HTML.

We need to read this value and pass it to the class below to validate it:

In C#:

In the code behind of your page :

string EncodedResponse = Request.Form["g-Recaptcha-Response"];bool IsCaptchaValid = (ReCaptchaClass.Validate(EncodedResponse) == "true" ? true : false);if (IsCaptchaValid) {    //Valid Request}

The Class:

  using Newtonsoft.Json;    public class ReCaptchaClass    {        public static string Validate(string EncodedResponse)        {            var client = new System.Net.WebClient();            string PrivateKey = "6LcH-v8SerfgAPlLLffghrITSL9xM7XLrz8aeory";            var GoogleReply = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", PrivateKey, EncodedResponse));            var captchaResponse = Newtonsoft.Json.JsonConvert.DeserializeObject<ReCaptchaClass>(GoogleReply);            return captchaResponse.Success.ToLower();        }        [JsonProperty("success")]        public string Success        {            get { return m_Success; }            set { m_Success = value; }        }        private string m_Success;        [JsonProperty("error-codes")]        public List<string> ErrorCodes        {            get { return m_ErrorCodes; }            set { m_ErrorCodes = value; }        }        private List<string> m_ErrorCodes;    }

In VB.NET:

In the code behind of your page :

Dim EncodedResponse As String = Request.Form("g-Recaptcha-Response")    Dim IsCaptchaValid As Boolean = IIf(ReCaptchaClass.Validate(EncodedResponse) = "True", True, False)    If IsCaptchaValid Then        'Valid Request    End If

The Class:

Imports Newtonsoft.JsonPublic Class ReCaptchaClass    Public Shared Function Validate(ByVal EncodedResponse As String) As String        Dim client = New System.Net.WebClient()        Dim PrivateKey As String = "6dsfH-v8SerfgAPlLLffghrITSL9xM7XLrz8aeory"        Dim GoogleReply = client.DownloadString(String.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", PrivateKey, EncodedResponse))        Dim captchaResponse = Newtonsoft.Json.JsonConvert.DeserializeObject(Of ReCaptchaClass)(GoogleReply)        Return captchaResponse.Success    End Function    <JsonProperty("success")> _    Public Property Success() As String        Get            Return m_Success        End Get        Set(value As String)            m_Success = value        End Set    End Property    Private m_Success As String    <JsonProperty("error-codes")> _    Public Property ErrorCodes() As List(Of String)        Get            Return m_ErrorCodes        End Get        Set(value As List(Of String))            m_ErrorCodes = value        End Set    End Property    Private m_ErrorCodes As List(Of String)End Class


Here's a version that uses the JavaScriptSerializer. Thanks Ala for the basis for this code.

WebConfig App Setting - I've added the secret key to the Web.Config in my case to allow transforms between environments. It can also be easily encrypted here if required.

<add key="Google.ReCaptcha.Secret" value="123456789012345678901234567890" />

The ReCaptcha Class - A simple class to post the response parameter along with your secret to Google and validate it. The response is deserialized using the .Net JavaScriptSerializer class and from that true or false returned.

using System.Collections.Generic;using System.Configuration;public class ReCaptcha{       public bool Success { get; set; }    public List<string> ErrorCodes { get; set; }    public static bool Validate(string encodedResponse)    {        if (string.IsNullOrEmpty(encodedResponse)) return false;        var client = new System.Net.WebClient();        var secret = ConfigurationManager.AppSettings["Google.ReCaptcha.Secret"];        if (string.IsNullOrEmpty(secret)) return false;        var googleReply = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secret, encodedResponse));        var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();        var reCaptcha = serializer.Deserialize<ReCaptcha>(googleReply);        return reCaptcha.Success;    }}

Validate The Response - Check the validity of the g-Recaptcha-Response form parameter in your Controller (or code behind for a web form) and take appropriate action.

var encodedResponse = Request.Form["g-Recaptcha-Response"];var isCaptchaValid = ReCaptcha.Validate(encodedResponse);if (!isCaptchaValid){    // E.g. Return to view or set an error message to visible}   


Most of these answers seem more complex than needed. They also dont specify the IP which will help prevent a interception attack (https://security.stackexchange.com/questions/81865/is-there-any-reason-to-include-the-remote-ip-when-using-recaptcha). Here's what I settled on

public bool CheckCaptcha(string captchaResponse, string ipAddress){    using (var client = new WebClient())    {        var response = client.DownloadString($"https://www.google.com/recaptcha/api/siteverify?secret={ ConfigurationManager.AppSettings["Google.ReCaptcha.Secret"] }&response={ captchaResponse }&remoteIp={ ipAddress }");        return (bool)JObject.Parse(response)["success"];    }}