Sitecore 9 Forms: Google reCaptcha field

Sitecore 9 Forms: Google reCaptcha field 

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

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

Sitecore 9 Forms Google reCaptcha field

Below you can find step by step process to create 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='https://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 class attribute.
  • 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 template which is required
    Sitecore 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 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 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);  
         }  
       }  
    
  • 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 below details:
    • Model Type: <Path>.RecaptchaValidate
    • Error Message: Invalid Captcha
  • Now go to Sitecore Form Editor and you will see Custom Captcha control inside Security tab
Sitecore 9 Forms Google reCaptcha field

  • Drag and drop control into your form
Sitecore 9 Forms Google reCaptcha field

  • Do not forget to select “Recaptcha Validate” on your submit action
Sitecore 9 Forms Google reCaptcha field
  • Render form into your page and Enjoy


Comments

  1. Hi Swati, thank you for a great article.

    I am trying to implement Google ReCaptcha V3

    I was able to implement following these steps. But I am facing just one issue. My Custom Submit Method is called twice and thus it results duplicate ReCaptcha verification.

    I have placed by Custom Submit item before Save Data in the Forms design.

    Could you please let me know what can be the issue? Any hints or response is much appreciated. Thank you.

    ReplyDelete
    Replies
    1. Is this happening for every submit action or only for Recaptcha validate?

      Delete
    2. Hi Swati. do you have any example for V3 Google Recaptcha ?

      Delete

Post a Comment

Popular Posts