Sitecore 9 Forms: Google reCaptcha field

Re-Captcha is the most important part of any form’s submission. Google reCaptcha runs an internet bot detector and determined whether a user is a bot or not.

Sitecore Forms does not provide the Google reCaptcha field, which was available in WFFM before, so I have created my custom Google reCaptcha.

recaptcha gif -

Below you can find step by step process to create the Google reCaptcha field.

  • Create patch config for reCaptcha Sitekey and SecretKey
<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore>
<settings>
<setting name="ReCaptchaSiteKey" value="site-key" />
<setting name="ReCaptchaSecretKey" value="secret-key" />  </settings>
</sitecore>
</configuration>
  • Create new viewmodel class RecaptchaViewModel.cs
 [Serializable()]  
   public class RecaptchaViewModel : MultipleLineTextViewModel  
   {  
     public string SiteKey { get; set; }  
     public string SecretKey { get; set; }  
     public string Message { get; set; }  
     protected override void InitItemProperties(Item item)  
     {  
       base.InitItemProperties(item);  
       string GoogleSiteKey = Configuration.Settings.GetSetting("ReCaptchaSiteKey");  
       string GoogleSecretKey = Configuration.Settings.GetSetting("ReCaptchaSecretKey");  
       if (!string.IsNullOrEmpty(GoogleSiteKey) && !string.IsNullOrEmpty(GoogleSecretKey))  
       {  
         SiteKey = GoogleSiteKey;  
         SecretKey = GoogleSecretKey;  
       }  
     }  
   } 
  • Create new CustomRecaptcha.cshtml file on this location “Website/Views/FormBuilder/FieldTemplates”
@model <Path>.RecaptchaViewModel
<script src='//www.google.com/recaptcha/api.js'></script>
<script>
$(document).ready(function () {
$('.recaptcha').click(function (e) {
var recaptchaResponse = grecaptcha.getResponse();
console.log(recaptchaResponse);
console.log(recaptchaResponse.length);
if (recaptchaResponse.length != 0) {
$('.googleRecaptchaClass').val(recaptchaResponse);
}
})
});
</script>
<span class="msg-error"></span>
<textarea id="@Html.IdFor(m => Model.Value)" class="googleRecaptchaClass" style="display:none;" name="@Html.NameFor(m => Model.Value)" data-sc-tracking="@Model.IsTrackingEnabled" data-sc-field-name="@Model.Name"></textarea>
<div class="g-recaptcha" data-sitekey="@Model.SiteKey"></div>
  • Move to this location “Website/Views/FormBuilder/FieldTemplates” and open “Button.cshtm” and add “recaptcha” class in the class attribute.Graphical user interface, text, application, email
  • In the Sitecore Content Editor, navigate to /sitecore/templates/System/Forms/Fields
  • Then add new template with name “CustomRecaptcha” and select Base template /sitecore/templates/System/Templates/Template
  • You can inherit the template which is requiredSitecore 9 Forms Google reCaptcha field
    • Switch to Core DB and create copy of this item “sitecore/client/Applications/FormsBuilder/Components/Layouts/PropertyGridForm/PageSettings/Settings/SingleLineText” with name “CustomRecaptcha”
    • Now move again to Master DB.
    • Create new Field type here “/sitecore/system/Settings/Forms/Field Types/Security” with name “CustomRecaptcha”
    • Fill in the below details:
      • View Path: FieldTemplates/CustomRecaptcha
      • Model Type:  <Namespace>. RecaptchaViewModel, <AssemblyName>
      • Property Editor: Property Editor Settings/CustomRecaptcha
      • Field Template: Fields/CustomRecaptcha

Custom reCaptcha Validation

  • Create a new submit action class RecaptchaValidate
public class RecaptchaValidate : SubmitActionBase<string>  
   {  
     /// <summary>  
     /// Initializes a new instance of the <see cref="LogSubmit"/> class.  
     /// </summary>  
     /// <param name="submitActionData">The submit action data.</param>  
     public RecaptchaValidate(ISubmitActionData submitActionData) : base(submitActionData)  
     {  
     }  
     /// <summary>  
     /// Tries to convert the specified <paramref name="value" /> to an instance of the specified target type.  
     /// </summary>  
     /// <param name="value">The value.</param>  
     /// <param name="target">The target object.</param>  
     /// <returns>  
     /// true if <paramref name="value" /> was converted successfully; otherwise, false.  
     /// </returns>  
     protected override bool TryParse(string value, out string target)  
     {  
       target = string.Empty;  
       return true;  
     }  
     /// <summary>  
     /// Executes the action with the specified <paramref name="data" />.  
     /// </summary>  
     /// <param name="data">The data.</param>  
     /// <param name="formSubmitContext">The form submit context.</param>  
     /// <returns>  
     ///  <c>true</c> if the action is executed correctly; otherwise <c>false</c>  
     /// </returns>  
     protected override bool Execute(string data, FormSubmitContext formSubmitContext)  
     {  
       if (!formSubmitContext.HasErrors)  
       {  
         RecaptchaViewModel googleRecaptchaFieldValue = formSubmitContext.Fields.Where(x => x is RecaptchaViewModel).FirstOrDefault() as RecaptchaViewModel;  
         if (googleRecaptchaFieldValue != null)  
         {  
           ISitecoreContext sitecoreContext = ServiceLocator.ServiceProvider.GetService<ISitecoreContext>();  
           var formSettings = sitecoreContext.GetItem<_FormSettings>(ItemIds.FormSettings);  
           if (formSettings != null && !string.IsNullOrEmpty(formSettings.SecretKey))  
           {  
             bool isCapthcaValid = ValidateCaptcha(googleRecaptchaFieldValue.Value, formSettings.SecretKey.ToString());  
             try  
             {  
               if (isCapthcaValid)  
               {  
                 return true;  
               }  
             }  
             catch  
             {  
               formSubmitContext.Abort();  
               return false;  
             }  
           }  
         }  
         formSubmitContext.Abort();  
         return false;  
       }  
       else  
       {  
         Logger.Warn(Invariant($"Form {formSubmitContext.FormId} submitted with errors: {string.Join(", ", formSubmitContext.Errors.Select(t => t.ErrorMessage))}."), this);  
       }  
       formSubmitContext.Abort();  
       return false;  
     }  
     public static bool ValidateCaptcha(string response, string secret)  
     {  
       string RecaptchaUrl = Configuration.Settings.GetSetting("GoogleApi");  
       var client = new WebClient();  
       var reply = client.DownloadString(RecaptchaUrl+"?secret=" + secret + "&response="+response);  
       var captchaResponse = JsonConvert.DeserializeObject<CaptchaResponse>(reply);  
       return System.Convert.ToBoolean(captchaResponse.Success);  
     }  
   }  
  • ItemIds.FormSettings is the Sitecore item id which contains the SecretKey field
  • For the GoogleApi key create a patch file like the below:
<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore>
<settings>
<setting name="GoogleApi" value="https://www.google.com/recaptcha/api/siteverify"/>
</settings>
</sitecore>
</configuration>
  • Create CaptchaResponse class
public class CaptchaResponse
{
[JsonProperty("success")]
public bool Success { get; set; }
[JsonProperty("error-codes")]
public List<string> ErrorMessage { get; set; }
}
    • Go to this location “/sitecore/system/Settings/Forms/Submit Actions”
    • Create new submit action “Recaptcha Validate” using this template “/sitecore/templates/System/Forms/Submit Action”
    • Fill in below details:
      • Model Type: <Path>.RecaptchaValidate
      • Error Message: Invalid Captcha
    • Now go to Sitecore Form Editor and you will see Custom Captcha control inside the Security tabSitecore 9 Forms Google reCaptcha field
    • Drag and drop control into your formSitecore 9 Forms Google reCaptcha field
    • Do not forget to select “Recaptcha Validate” on your submit actionSitecore 9 Forms Google reCaptcha field
      • Render form into your page and Enjoy

 

This article originally appeared on SWATI GUPTA (SITECORE MVP) | BLOGS (https://swatiguptablogs.blogspot.com/).