Sitecore - Google ReCaptcha V3
Chandra Kodi
Posted on February 11, 2021
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.
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);
}
}
- 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;
}
}
- 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>
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
Create new Validation item at
/sitecore/system/Settings/Forms/Validations
asCaptchaV3 Validation
.
Create new Field type at
/sitecore/system/Settings/Forms/Field Types/Security
with nameGoogle Recaptcha V3
.
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
.
That's it. The ReCaptcha V3 is ready!
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
Posted on February 11, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.