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.
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='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 the 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 the template which is required
- 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 tab
- Drag and drop control into your form
- Do not forget to select “Recaptcha Validate” on your submit actionRender form into your page and Enjoy
This article originally appeared on SWATI GUPTA (SITECORE MVP) | BLOGS (https://swatiguptablogs.blogspot.com/).