如何在ASP.NET项目中添加验证码

How to add captcha in ASP.NET project

我想在我的 ASP.NET 应用程序的登录视图中添加验证码。该视图非常简单,只有电子邮件和密码文本框。现在在电子邮件和密码文本框下方,我想在我的登录表单中添加验证码。

我查看了许多关于添加验证码的文章,并在 ASP.NET 中发现验证码 MVC 5 使用起来非常简单,但是当我将它添加到我的应用程序时。

不再显示验证码图像,而是开始显示十字符号。

我已经检查了所有配置,执行没有任何问题。在 ASP.NET 应用程序中是否有任何其他最简单的方法来添加验证码?

下面是我最新项目之一的完整实现 - 它只是遵循 Google 的 Recaptcha 指南和一些额外的有用代码 - 请 check the latest Google documentation 获取最新更新:

在您的 web.config 文件中添加 2 个新密钥 - 一个用于站点密钥,另一个用于密钥 - 当您从 the Google Recaptcha portal.[=20 注册您的网站时,您将获得这些值=]

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

创建一个 public 静态配置 class 以轻松达到您的 web.config 键值,如下所示;

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];
    }
}

将 g-recaptcha 部分添加到您的视图中,即

        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>

同一视图的脚本部分;

@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>
}

将 RecaptchaToken 添加到您的视图模型;

 public string RecaptchaToken { get; set; }

这是您的 post 操作以及如何验证您的 recapcha 令牌并添加一些自定义验证错误:

    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));
    }

用于验证 recapcha 令牌的 StringExtension:

 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;
            }
        }
    }

事情是这样的: