Jim Kiely
Jim Kiely

Reputation: 385

ReCaptcha Post Using C# in MVC Application

I'm trying to do a direct post to Google using this code. I keep getting an error, "invalid private key". I have double checked it and even had someone else double check it. The reason i'm going it this way is because I'm using javascript and ajax to pass the variables to this function.

[HttpPost]
    public string ValidateReCaptcha(string captchaChallenge, string captchaResponse)
    {
        if (captchaChallenge != null && captchaResponse != null)
        {
            string strPrivateKey = System.Web.Configuration.WebConfigurationManager.AppSettings["recaptchaPrivateKey"].ToString();
            string strParameters = "?privatekey=" + strPrivateKey +
                "&remoteip=" + HttpContext.Request.UserHostAddress.ToString() +
                "&challenge=" + captchaChallenge +
                "&response=" + captchaResponse;

            WebRequest request = WebRequest.Create("http://www.google.com/recaptcha/api/verify");
            request.Method = "POST";
            string postData = strParameters;
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = byteArray.Length;
            Stream dataStream = request.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();
            WebResponse response = request.GetResponse();
            dataStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(dataStream);
            string responseFromServer = reader.ReadToEnd();

            if (responseFromServer.ToString() != "true")
            {
                errorCodeList.Add(8);
                return responseFromServer + strPrivateKey;
            }
            else
            {
                return responseFromServer;
            }
            // Clean up the streams.
            reader.Close();
            dataStream.Close();
            response.Close();
        }
        else
        {
            errorCodeList.Add(8);
            return null;
        }
    }

Upvotes: 1

Views: 1548

Answers (3)

MahmutKarali
MahmutKarali

Reputation: 365

You can try like this basically. I got affirmative result !!!

 public async Task<bool> ReCaptcha(Recaptcha recaptcha)
 {
    string secretKey = "YOUR_PRIVATE_KEY";
    HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.PostAsync(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secretKey, recaptcha.Response), null);

    if (response.IsSuccessStatusCode)
    {
        var resultString = await response.Content.ReadAsStringAsync();
        RecaptchaResponse resp = JsonConvert.DeserializeObject<RecaptchaResponse>(resultString);
        if (resp.success)
        {
             return true;
        }
     }
     return false;
 }

Upvotes: 0

user1626116
user1626116

Reputation: 183

I guess you need to delete ? on post data.

I've changed the code for me, and this works

 private bool ValidarCaptcha(UsuarioMV usuarioMV)
    {
        Stream dataStream = null;
        WebResponse response = null;
        StreamReader reader = null;

        try
        {
            string captchaChallenge = usuarioMV.sCaptchaChallenge;
            string captchaResponse = usuarioMV.sCaptchaResponse;
            if (captchaChallenge != null
                && captchaResponse != null)
            {
                throw new Exception("Parametros captcha nulos.");
            }
            WebRequest request = WebRequest.Create("https://www.google.com/recaptcha/api/verify");
            request.Method = "POST";

            //Solicitud
            string strPrivateKey = System.Web.Configuration.WebConfigurationManager.AppSettings["RecaptchaPrivateKey"].ToString();

            NameValueCollection outgoingQueryString = HttpUtility.ParseQueryString(String.Empty);
            outgoingQueryString.Add("privatekey", strPrivateKey);
            outgoingQueryString.Add("remoteip", "localhost");
            outgoingQueryString.Add("challenge", captchaChallenge);
            outgoingQueryString.Add("response", captchaResponse);
            string postData = outgoingQueryString.ToString();

            byte[] byteArray = Encoding.UTF8.GetBytes(postData);
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = byteArray.Length;

            //Respuesta
            dataStream = request.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();
            response = request.GetResponse();
            dataStream = response.GetResponseStream();
            reader = new StreamReader(dataStream);

            if (reader.ReadLine() != "true")
            {
                string sLinea = reader.ReadLine();
                //if the is another problem
                if (sLinea != "incorrect-captcha-sol")
                {
                    throw new Exception(sLinea);
                }

                return false;
            }
            else
            {
                return true;
            }
        }
        catch (Exception ex)
        {
            throw;
        }
        finally
        {
            //Clean up the streams.
            if (reader != null)
                reader.Close();
            if (dataStream != null)
                dataStream.Close();
            if (response != null)
                response.Close();
        }
    }

Upvotes: 0

Sean
Sean

Reputation: 882

The "return" in the IF/ELSE means thet that the "Clean up the streams" code is unreachable and as the return withing the IF would end the execution, this could be simplified a little:

[HttpPost]
public string ValidateReCaptcha(string captchaChallenge, string captchaResponse)
{
    if (captchaChallenge != null && captchaResponse != null)
    {
        // original code, remains unchanged
        /*
          ...snipped for clarity
        */

        // Clean up the streams (relocated to make it reachable code)
        reader.Close();
        dataStream.Close();
        response.Close();

        if (responseFromServer.ToString() != "true")
        {
            errorCodeList.Add(8);
            return responseFromServer + strPrivateKey; // "IF" ends execution here
        }
        return responseFromServer; // "ELSE" ends execution here
    }
    errorCodeList.Add(8);
    return null;
}

Upvotes: 0

Related Questions