1

我在我的 WebForms 应用程序中多次使用reCAPTCHA 。现在我想将它添加到 ASP.NET MVC 应用程序中。

我在RecaptchaControlMvc中发现了一些看起来不错的代码,但令人难以置信的是,我无法找到有关如何使用此控件的单个段落或示例。

我已经在 Google reCAPTCHA 组中发帖,但它已经死了。

谁能指出一个使用这个控件的例子,一个关于如何使用它的段落,或者建议一个替代方案?

注意:我知道在 stackoverflow 上有类似的问题,但我发现没有一个讨论如何使用这个控件。

4

3 回答 3

2

这里有一些代码

您添加这样的属性:

[CaptchaValidator]  
[AcceptVerbs( HttpVerbs.Post )]  
public ActionResult SubmitForm( Int32 id, bool captchaValid )  
{  
.. Do something here  
}  

您在视图中呈现验证码:

<%= Html.GenerateCaptcha() %> 

这是这样的:

public static string GenerateCaptcha( this HtmlHelper helper )  
{           
    var captchaControl = new Recaptcha.RecaptchaControl  
            {  
                    ID = "recaptcha",  
                    Theme = "blackglass",  
                PublicKey = -- Put Public Key Here --,  
                        PrivateKey = -- Put Private Key Here --  
            };  

    var htmlWriter = new HtmlTextWriter( new StringWriter() );  
    captchaControl.RenderControl(htmlWriter);  
    return htmlWriter.InnerWriter.ToString();  
}  
于 2013-07-26T13:49:41.467 回答
1

我可以为您提供一种简单的替代方法来使用 google recaptcha。在这里你可以找到关于Google new reCAPTCHA using asp.net mvc的完整参考

首先,你们所有人都需要注册并生成 Google reCAPTCHA API。转到http://www.google.com/recaptcha然后点击右上角的 Get reCAPTCHA 按钮

其次,在你的视图中编写 html 代码。在此处替换文本“您的站点密钥

@{
    ViewBag.Title = "Index";
}
<h2>Index</h2>
<div>
    @using (Html.BeginForm("FormSubmit", "Home", FormMethod.Post))
{
    <div class="g-recaptcha" data-sitekey="Your sitekey here"></div>
    <input type="submit" value="Submit" />
}
</div>
<span style="display:inline-block; font-size:20px;margin:20px 0;padding:20px;border:1px solid #D3D3D3">
    @ViewBag.Message
</span>
<script src='https://www.google.com/recaptcha/api.js' type="text/javascript"></script>

第三次也是最后一次,编写验证 google reCaptcha 的操作代码

[HttpPost]
public ActionResult FormSubmit()
{
    //Validate Google recaptcha here
    var response = Request["g-recaptcha-response"];
    string secretKey = "Your secret here";
    var client = new WebClient();
    var result = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secretKey, response));
    var obj = JObject.Parse(result);
    var status = (bool)obj.SelectToken("success");
    ViewBag.Message = status ? "Google reCaptcha validation success" : "Google reCaptcha validation failed";

    //When you will post form for save data, you should check both the model validation and google recaptcha validation
    //EX.
    /* if (ModelState.IsValid && status)
    {

    }*/

    //Here I am returning to Index page for demo perpose, you can use your view here
    return View("Index");
}
于 2015-12-16T11:27:56.930 回答
1

这就是我使用 ASP.Net MVC 和 ReCaptcha 3 的方式。

  1. 在 Visual Studio 2015 或 2017 中,创建一个新的 ASP.NET MVC 项目并将目标 .NET Framework 设置为 4.6.2。
  2. 为您的 ASP.NET MVC 项目创建一个描述性名称(例如 ASPNetMVCWithReCaptcha3)。
  3. 构建您的应用程序并确保它可以编译并且没有错误。
  4. 在 Web.Config 中,创建两个新密钥,然后从保存这些引用的文本编辑器中复制/粘贴站点密钥和密钥。
<appSettings>
    <add key="reCaptchaSiteKey" value="site_key" />
    <add key="reCaptchaSecretKey" value="secret_key" />
</appSettings>
  1. 在“模型”文件夹中,创建一个新类“ReCaptchaForm.cs”并复制/粘贴以下代码行。
namespace ASPNetMVCWithReCaptcha3.Models
{
    public class ReCaptchaForm
    {
        public string Message { get; set; }
    }
}
  1. 在项目中创建一个新的“类”文件夹。
  2. 在“Classes”文件夹中,创建一个新类“ReCaptcha.cs”并复制/粘贴以下代码行:
using System;
using System.Web;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Net.Http;
using System.Configuration;

namespace ASPNetMVCWithReCaptcha3.Classes
{
}
  1. 在命名空间内添加以下行

    • 添加一个类“GoogleReCaptchaVariables”,它将存储呈现 ReCaptcha 所需的变量。
public static class GoogleReCaptchaVariables
{
     public static string ReCaptchaSiteKey = ConfigurationManager.AppSettings["reCaptchaSiteKey"]?.ToString() ?? string.Empty;
     public static string ReCaptchaSecretKey = ConfigurationManager.AppSettings["reCaptchaSecretKey"]?.ToString() ?? string.Empty;
     public static string InputName = "g-recaptcha-response";
}
  • 创建一个帮助器类来呈现响应令牌的隐藏输入。
public static class ReCaptchaHelper
{
     public static IHtmlString ReCaptchaHidden(this HtmlHelper helper)
     {
          var mvcHtmlString = new TagBuilder("input")
          {
               Attributes =
               {
                    new KeyValuePair<string, string>("type", "hidden"),
                    new KeyValuePair<string, string>
                           ("id", GoogleReCaptchaVariables.InputName),
                    new KeyValuePair<string, string>
                           ("name", GoogleReCaptchaVariables.InputName)
               }
          };
          string renderedReCaptchaInput = 
                   mvcHtmlString.ToString(TagRenderMode.Normal);
          return MvcHtmlString.Create($"{renderedReCaptchaInput}");
     }

     public static IHtmlString ReCaptchaJS
             (this HtmlHelper helper, string useCase = "homepage")
     {
          string reCaptchaSiteKey = GoogleReCaptchaVariables.ReCaptchaSiteKey;
          string reCaptchaApiScript = "<script 
          src='https://www.google.com/recaptcha/api.js?render=" + 
          reCaptchaSiteKey + "'></script>;";
          string reCaptchaTokenResponseScript = "<script>
          $('form').submit(function(e) { e.preventDefault(); 
          grecaptcha.ready(function() { grecaptcha.execute('" + 
          reCaptchaSiteKey + "', {action: '" + useCase + 
          "'}).then(function(token) { $('#" + 
          GoogleReCaptchaVariables.InputName + "').val(token); 
          $('form').unbind('submit').submit(); }); }); }); </script>;";
          return MvcHtmlString.Create
                 ($"{reCaptchaApiScript}{reCaptchaTokenResponseScript}");
     }
}
  • 添加另一个呈现“span”标签的帮助器类,以在 ReCaptcha 验证失败时显示错误消息。
public static IHtmlString ReCaptchaValidationMessage
             (this HtmlHelper helper, string errorText = null)
{
     var invalidReCaptchaObj = 
            helper.ViewContext.Controller.TempData["InvalidCaptcha"];
     var invalidReCaptcha = invalidReCaptchaObj?.ToString();
     if (string.IsNullOrWhiteSpace(invalidReCaptcha)) 
                          return MvcHtmlString.Create("");
     var buttonTag = new TagBuilder("span")
     {
          Attributes = {
               new KeyValuePair<string, string>("class", "text-danger")
          },
          InnerHtml = errorText ?? invalidReCaptcha
     };
     return MvcHtmlString.Create(buttonTag.ToString(TagRenderMode.Normal));
}
  • 接下来,创建一个属性“ValidateReCaptchaAttribute”来处理 API 调用。添加一个内部类“ResponseToken”来存储响应数据。然后,实现验证逻辑以在验证失败时显示错误消息。
public class ValidateReCaptchaAttribute : ActionFilterAttribute
{
     public override void OnActionExecuting(ActionExecutingContext filterContext)
     {
          string reCaptchaToken = 
          filterContext.HttpContext.Request.Form[GoogleReCaptchaVariables.InputName];
          string reCaptchaResponse = ReCaptchaVerify(reCaptchaToken);
          ResponseToken response = new ResponseToken();
          if (reCaptchaResponse != null)
          {
               response = Newtonsoft.Json.JsonConvert.DeserializeObject
                          (reCaptchaResponse);
          }
          if (!response.Success)
          {
               AddErrorAndRedirectToGetAction(filterContext);
          }
          base.OnActionExecuting(filterContext);
     }

     public string ReCaptchaVerify(string responseToken)
     {
          const string apiAddress = 
                   "https://www.google.com/recaptcha/api/siteverify";
          string recaptchaSecretKey = GoogleReCaptchaVariables.ReCaptchaSecretKey;
          string urlToPost = $"{apiAddress}
          ?secret={recaptchaSecretKey}&response={responseToken}";
          string responseString = null;
          using (var httpClient = new HttpClient())
          {
               try
               {
                   responseString = httpClient.GetStringAsync(urlToPost).Result;
               }
               catch
               {
                   //Todo: Error handling process goes here
               }
           }
           return responseString;
      }

      private static void AddErrorAndRedirectToGetAction
      (ActionExecutingContext filterContext, string message = null)
      {
           filterContext.Controller.TempData["InvalidCaptcha"] = 
           message ?? "Invalid Captcha! The form cannot be submitted.";
           filterContext.Result = 
                 new RedirectToRouteResult(filterContext.RouteData.Values);
      }

      internal class ResponseToken
      {
           public bool Success { get; set; }
           public float Score { get; set; }
           public string Action { get; set; }
           public DateTime Challenge_TS { get; set; }
           public string HostName { get; set; }
           public List ErrorCodes { get; set; }
      }
 }
  • 在控制器中,创建一个实现 [ValidateReCaptcha] 属性的回发操作。
[HttpPost]
[ValidateAntiForgeryToken]
[ValidateReCaptcha]
public ActionResult Index(ReCaptchaForm form)
{
     return View(form);
}
  • 在您的控制器视图中,添加以下行以呈现表单、消息输入和提交底部。
@model ASPNetMVCWithReCaptcha3.Models.ReCaptchaForm
@using ASPNetMVCWithReCaptcha3.Classes;
@{
    ViewBag.Title = "ReCaptcha Form";
}
@using (Html.BeginForm())
{
     @Html.AntiForgeryToken()
     @Html.LabelFor(model => model.Message)
     @Html.TextAreaFor(model => model.Message, new { @class = "form-control" })
     @Html.ReCaptchaValidationMessage()
     @Html.ReCaptchaHidden()
     @Html.ReCaptchaJS()
     <button type="submit" class="btn btn-primary">Send Message</button>
}
  1. 构建项目并确保它没有错误。因此,如果 ReCaptcha API 返回成功响应,则应提交表单。相反,如果 API 返回失败的响应,则错误消息将显示在消息输入的底部。
于 2019-06-16T03:39:57.810 回答