Sitecore - Google ReCaptcha V3

chandra_kodi

Chandra Kodi

Posted on February 11, 2021

Sitecore - Google ReCaptcha V3

Google developed reCaptcha V3 to improve the accuracy of bot detection and for better user experience. Unlike V2, V3 is transparent as a hidden element and continuously monitors the visitor’s behavior to determine whether it’s a human or a bot.
alt text

Below you can find step by step process to create Google reCaptcha V3 field in Sitecore Forms.

  • Create a new model class - GoogleRecaptchaV3.cs
public class GoogleRecaptchaV3 : StringInputViewModel
    {
        public string ApiKey { get; set; }

        public string ErrorMessage { get; set; }

        protected override void InitItemProperties(Item item)
        {
            base.InitItemProperties(item);

            ApiKey = Sitecore.StringUtil.GetString(item.Fields["Api Key"]);
            ErrorMessage = Sitecore.StringUtil.GetString(item.Fields["Error Message"]);
        }

        protected override void UpdateItemFields(Item item)
        {
            base.UpdateItemFields(item);

            item.Fields["Api Key"].SetValue(ApiKey, true);
            item.Fields["Error Message"].SetValue(ErrorMessage, true);
        }
    }
Enter fullscreen mode Exit fullscreen mode
  • Create custom validation class - CaptchaV3Validator.cs
public class CaptchaV3Validator : ValidationElement<string>
    {
        public override IEnumerable<ModelClientValidationRule> ClientValidationRules
        {
            get
            {
                if (string.IsNullOrEmpty(this.ApiKey))
                {
                    yield break;
                }
            }
        }

        protected virtual string ApiKey { get; set; }
        protected virtual string Title { get; set; }
        protected virtual string FieldName { get; set; }

        public CaptchaV3Validator(ValidationDataModel validationItem) : base(validationItem)
        {

        }

        public override void Initialize(object validationModel)
        {
            base.Initialize(validationModel);
            StringInputViewModel stringInputViewModel = validationModel as StringInputViewModel;
            if (stringInputViewModel != null)
            {
                var fieldItem = Sitecore.Context.Database.GetItem(ID.Parse(stringInputViewModel.ItemId));
                if (fieldItem != null)
                {
                    this.ApiKey = fieldItem["Api Key"];
                }
                this.Title = stringInputViewModel.Title;
                this.FieldName = stringInputViewModel.Name;
            }
        }

        public override ValidationResult Validate(object value)
        {
            if (value == null)
            {
                return new ValidationResult("Captcha is Inavlid.");// ValidationResult.Success;
            }
            var isCaptchaValid = ValidateCaptcha((string)value, this.ApiKey);
            if (!isCaptchaValid)
            {
                return new ValidationResult(this.FormatMessage(new object[] { this.Title }));
            }
            return ValidationResult.Success;
        }
        public static bool ValidateCaptcha(string response, string secret)
        {
            HttpClient httpClient = new HttpClient();

            var res = httpClient.GetAsync($"https://www.google.com/recaptcha/api/siteverify?secret=" + secret + "&response=" + response + "").Result;

            if (res.StatusCode != HttpStatusCode.OK)
                return false;

            string JSONres = res.Content.ReadAsStringAsync().Result;
            dynamic JSONdata = JObject.Parse(JSONres);

            if (JSONdata.success != "true")
                return false;

            return true;
        }
    }
Enter fullscreen mode Exit fullscreen mode
  • Create a View at location Views/FormBuilder/FieldTemplates- GoogleRecaptchaV3.cshtml
@using Sitecore.ExperienceForms.Mvc.Html
@model Glass.Mapper.Training.FormFields.GoogleRecaptchaV3


<input id="@Html.IdFor(m => Model.Value)" name="@Html.NameFor(m => Model.Value)" class="@Model.CssClass" type="hidden" value="" />

<script src="https://www.google.com/recaptcha/api.js?onload=grecaptcha_ready&render=@Model.ApiKey"></script>
<script>
    function grecaptcha_ready() {
        grecaptcha.ready(function () {
            grecaptcha.execute('@Model.ApiKey', { action: 'form' }).then(function (token) {
                document.getElementById("@Html.IdFor(m => Model.Value)").value = token;
            });
        });
    }
    var hiddenField = document.getElementById(@Html.Raw("\"" + Html.IdFor(m => Model.Value) + "\""));
    var parent = hiddenField.parentNode;
    if (parent.classList.contains("sc-formdesign-fieldcontainer")) {
        var textDiv = document.createElement("div");
        textDiv.innerHTML = "(ReCaptcha V3 Hidden Field)";
        parent.appendChild(textDiv);
    }
</script>
Enter fullscreen mode Exit fullscreen mode

Let's move on to the sitecore item changes.

CORE db

  • Create a form property by copying one of existing items ”SingleLineText” and rename the copied item as “GoogleReCaptchaV3”. /sitecore/client/Applications/FormsBuilder/Components/Layouts/PropertyGridForm/PageSettings/Settings/GoogleReCaptchaV3

MASTER db

  • In the Sitecore Content Editor, navigate to /sitecore/templates/System/Forms/Fields.
  • Then add new template with name “CustomRecaptchaV3” and select Base template /sitecore/templates/System/Templates/Template
    alt text

  • This template must inherit as below
    alt text

  • Create new Validation item at /sitecore/system/Settings/Forms/Validations as CaptchaV3 Validation.
    alt text

  • Create new Field type at /sitecore/system/Settings/Forms/Field Types/Security with name Google Recaptcha V3.
    alt text

o View Path: FieldTemplates/GoogleRecaptchaV3
o Model Type: <Namespace>.GoogleRecaptchaV3, <AssemblyName>
o Allowed Validations: CaptchaV3 Validation
o Property Editor: Property Editor Settings/GoogleReCaptchaV3
o Field Template: Fields/Google ReCaptcha V3
o Icon: OfficeWhite/32x32/lock3.png
o BackgroundColor Color: Tomato

Now we are ready to use ReCaptcha V3 in Forms. Go to Sitecore Forms and simply drag and drop Google ReCaptcha V3 field under Security.
alt text

That's it. The ReCaptcha V3 is ready!
alt text

Note: reCAPTCHA v3 returns a score for each request without user friction. The score (between 0 and 1) is based on interactions with your site and you should update script to make decision based on the score according to your application needs. Also, I haven't included token validity but if the default 2 minutes is not enough, then you have to renew/refresh for every two minutes per google's documentation: https://developers.google.com/recaptcha/docs/verify#token_restrictions

💖 💪 🙅 🚩
chandra_kodi
Chandra Kodi

Posted on February 11, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related