Google reCaptcha v2

Hi,

I’m trying to implement reCaptcha version 2 on my umbraco v7 build that is already live.
Now I have the client-side verification working and would like to verify the key that’s provided with google.
It would be ideal if I could do this with javascript but would be grateful for any solution that would work.

Thanks in advance for any help you can provide.
James


This is a companion discussion topic for the original entry at https://our.umbraco.com/forum/99473-google-recaptcha-v2

Hi James,

Google ReCaptcha V2 has following steps

  1. User complete validation on page, which generates token. This is done via javascript on page.
  2. This token then need to be validated on Server. If this validation is not done then form post can still be done by by-passing Javascript. This can be achieved by writing a simple http POST script

Simple add this method to your Controller (or SurfaceController in Umbraco)

private async Task<bool> ValidateReCaptchaV2()
        {
			home = Umbraco.ContentAtRoot().FirstOrDefault();
			//Validate ReCaptcha Using HttpClient
			if (!string.IsNullOrEmpty(home.Value<string>("RecaptchaSiteKey")))
            {
                var captchaResponse = Request.Form["recaptchaCode"];
                var secretKey = home.Value<string>("ReCaptchaSecretKey");
                var apiUrl = "https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}";
                var requestUri = string.Format(apiUrl, secretKey, captchaResponse);
                
                //PROXY Settings implemented through Web.Config
                /*
                //Setup the Proxy otherwise its failing on IONOS Web Hosting
				//WebRequest wrGETURL;
				//wrGETURL = WebRequest.Create(TextBox1.Text);
				WebProxy ionosProxy = new WebProxy("http://winproxy.server.lan:3128/", true);
				//wrGETURL.Proxy = myProxy;
                				// Create a client handler that uses the proxy
				var httpClientHandler = new HttpClientHandler
				{
					Proxy = ionosProxy,
				};
                				// Disable SSL verification
				httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
                var client = new HttpClient(handler: httpClientHandler, disposeHandler: true);
                */

                var client = new HttpClient();

				using (var response = client.GetAsync(requestUri))
                {
                    var jsonString = await response.Result.Content.ReadAsStringAsync();
                    if (response.IsCompleted)
                    {
                        var result = JObject.Parse(jsonString);
                        //https://developers.google.com/recaptcha/docs/verify json format
                        return result.Value<bool>("success");
                    }
                }
            }

			return true;
        }

Request.Form[“recaptchaCode”] is the code you receive when user completes javascript action
ReCaptchaSecretKey - this is what you required to use when calling Google ReCaptcha Api for validation. You can store this in Web.Config file as well.

The front-end code

@using Website.Controllers
@model Website.Models.ContactFormModel

@{
    bool isFormSubmitted = Convert.ToBoolean(TempData["IsEmailSent"]);
    bool isError = Convert.ToBoolean(TempData["IsError"]);
}

@using (Html.BeginUmbracoForm<ContactFormController>(nameof(ContactFormController.Submit), null, new {@id = "contactform", @class = "law-cform form-style-2" }, FormMethod.Post))
{
    <div class="row">
        <div class="col-sm-12 px-2">
            <h4 class="form-title text-center">
                Contact Us
            </h4>
        </div>
        @if (isError)
        {
            <div class="col-sm-12 px-2">
                <div class="text-center">
                    <p class="alert-danger">An error occured, please try again or call our number.</p>
                </div>
            </div>
        }
        @if (!isFormSubmitted)
        {
            <div class="col-sm-12 px-2">
                <div class="contact-field">
                    @Html.TextBoxFor(x => x.Name, new { placeholder = "Name", required = true })
                </div>
            </div>
            <div class="col-sm-12 px-2">
                <div class="contact-field">
                    @Html.TextBoxFor(x => x.Email, new { placeholder = "Email", required = true })
                </div>
            </div>
            <div class="col-sm-12 px-2">
                <div class="contact-field">
                    @Html.TextBoxFor(x => x.Phone, new { placeholder = "Phone", required = true })
                </div>
            </div>
            <div class="col-sm-12 px-2">
                <div class="contact-field mb-0">
                    @Html.TextAreaFor(x => Model.Message, new { placeholder = "Message...", rows = "3", required = true })
                </div>
            </div>
            if (!string.IsNullOrEmpty(Model.RecaptchaSiteKey))
            {
                <div class="g-recaptcha" data-sitekey="@Model.RecaptchaSiteKey" data-callback="reCaptchaCallBack"></div>
                <label id="lblMessage" runat="server" clientidmode="static" class="error"></label>
                <input type="hidden" id="recaptchaCode" name="recaptchaCode" value="" />
                @Html.HiddenFor(x => x.RecaptchaSiteKey)
            }
            @Html.HiddenFor(x => x.EmailToAddress)
            @Html.HiddenFor(x => x.EmailSubject)
            <div class="col-sm-12 px-2">
                <button type="button" name="Submit" value="Submit" class="mt-btn mt-btn-form" onclick="SubmitButtonClicked();">Submit</button>
            </div>
        }
        else
        {
            <div class="col-sm-12 px-2">
                <div class="text-center">
                    <p>Thanks for your enquiry, one of our team members will contact you shortly.</p>
                </div>
            </div>
        }
    </div>
}

@if (!string.IsNullOrEmpty(Model.RecaptchaSiteKey))
{
    <script>
        var reCaptchaCallBack = function (response) {
            console.log(response);
            $("#recaptchaCode").val(response);
        }
    </script>
}

<script>
    var SubmitButtonClicked = function () {
        var isSubmitOk = true;
        //Check for ReCaptcha
        if ($(".g-recaptcha").length) {
            console.log($(".g-recaptcha").length);
            if ($("#recaptchaCode").val().length > 0) {
                isSubmitOk = true;
            }
            else {
                jQuery('#lblMessage').html("Please check ReCaptcha");
                isSubmitOk = false;
            }
        }

        if (isSubmitOk) {
            $("form#contactform").submit();
        }
        
    }
</script>

You will also need cdn to handle ajax call and the Google recaptcha api https://www.google.com/recaptcha/api.js, you may already have this