skip to Main Content

I want add captcha in login view for my ASP.NET application. The view is quite simple has only email and password text box. Now below the email and password text box I want to add captcha in my login form.

I have look into many articles about adding captcha and found Captcha in ASP.NET MVC 5 is quite simple to use but when I added it to my app.

Instead of showing captcha image it starts displaying a cross symbol.

I have checked all the configuration already there is nothing wrong with the implementation. Is there any other easiest way to add captcha in ASP.NET app ?

2

Answers


  1. Chosen as BEST ANSWER

    Hey Thanks everyone for the suggestions. So the cross symbol was occurred due to the security header named referrer-policy in web.config. When i removedthis header. Captcha was successfully displayed jn my app.


  2. Below is the full implementation from one of my latest projects – it simply follows Google’s Recaptcha guidance with some additional useful code – please check the latest Google documentation for the latest updates:

    Add 2 new keys in your web.config file – one for the site key and the other for the secret key – you get these values when you register your website from the Google Recaptcha portal.

      <add key="RECAPTCHA:SITE_KEY" value="Your site key that you generate from " />
      <add key="RECAPTCHA:SECRET_KEY" value="Your secret key" />
    

    Create a public static Config class to reach your web.config key values easily as follows;

    public static class Config
    {
        private static NameValueCollection _appSettings;
    
        private static NameValueCollection AppSettings => _appSettings ?? (_appSettings = ConfigurationManager.AppSettings);
    
        public static string RecaptchaSiteKey => GetStringValueOrDefault("RECAPTCHA:SITE_KEY", "");
    
        public static string RecaptchaSecretKey => GetStringValueOrDefault("RECAPTCHA:SECRET_KEY", "");
    
        private static string GetStringValueOrDefault(string key, string defaultValue)
        {
            return string.IsNullOrWhiteSpace(GetStringValueFromAppSettings(key))
                    ? defaultValue
                    : GetStringValueFromAppSettings(key);
        }
    
        private static string GetStringValueFromAppSettings(string key)
        {
            return string.IsNullOrEmpty(AppSettings[key]) ? string.Empty : AppSettings[key];
        }
    }
    

    Add the g-recaptcha section to your view, i.e.

            if (ViewData.ModelState.Keys.Contains("OverallError"))
            {
                <div class="form__row">
                    @Html.ValidationMessage("OverallError", new { @class = "form__error" }).Raw()
                </div>
            }
            <div class="form__row">
                <div class="form__controls">
                    <div class="g-recaptcha"
                         data-sitekey="@YourProject.Config.RecaptchaSiteKey"
                         data-callback="reCaptchaResponse">
                    </div>
                    @Html.HiddenFor(m => m.RecaptchaToken)
                </div>
            </div>
            <div class="form__row form__row--final">
                <div class="form__controls">
                    <button type="submit" class="button button--primary" id="createAccountSubmit">Create account</button>
                </div>
            </div>
    

    Script section on the same view;

    @section Scripts {
        <script>
            $(document).ready(function () {
                createAccountSubmit.disabled = true;
            });
    
            var createAccountSubmit = document.getElementById("createAccountSubmit");
    
            function reCaptchaResponse(token) {
                $('#RecaptchaToken').val(token);
                createAccountSubmit.disabled = false;
            }
        </script>
        <script src="https://www.google.com/recaptcha/api.js" async defer></script>
    }
    

    Add RecaptchaToken to your viewmodel;

     public string RecaptchaToken { get; set; }
    

    And here is your post action and how you can validate your recapcha token and add some custom validation errors:

        if (ModelState.IsValid)
        {
            if (!await model.RecaptchaToken.ValidateAsRecapchaToken())
            {
                ModelState.AddModelError("OverallError", "CAPTCHA validation failed. Please try again.");
            }
    
            // Always clear the token as it is no longer valid. Any subsequent re-posts will need a new token.
            ModelState.SetModelValue(nameof(model.RecaptchaToken), new ValueProviderResult("", "", CultureInfo.InvariantCulture));
        }
    

    StringExtension to validate the recapcha token:

     public static class StringExtensions
        {
           public static async Task<bool> ValidateAsRecapchaToken(this string token)
            {
                using (var client = new HttpClient())
                {
                    var secret = Config.RecaptchaSecretKey;
                    var url = $"https://www.google.com/recaptcha/api/siteverify?secret={secret}&response={token}";
                    var response = await client.PostAsync(url, new StringContent(""));
                    var responseModel = await response.Content.ReadAsAsync<RecaptchaResponseModel>();
    
                    return responseModel.Success;
                }
            }
        }
    

    This is how things look like:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search