将reCAPTCHA与ASP.NET MVC一起使用

时间:2013-07-26 13:44:12

标签: c# asp.net-mvc recaptcha

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

我在RecaptchaControlMvc中找到了一些好的代码,但令人难以置信的是,我无法找到关于如何使用此控件的单个段落或示例。

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

有人能指出一个使用此控件的示例,一个关于如何使用它的段落,或建议一个替代方案吗?

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

3 个答案:

答案 0 :(得分:2)

一些代码here

您可以添加如下属性:

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

答案 1 :(得分: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. 在项目中创建一个新的“ Classes”文件夹。
  2. 在“类”文件夹中,创建一个新类“ 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”以处理A​​PI调用。添加一个内部类“ 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返回了失败的响应,则错误消息将显示在消息输入的底部。

答案 2 :(得分:0)

我可以为您提供一种使用google recaptcha的简单替代方法。 在这里,您可以找到有关Google new reCAPTCHA using asp.net mvc

的完整参考资料

首先,所有人都需要注册&amp;生成Google reCAPTCHA API。 转到http://www.google.com/recaptcha,然后点击右上角的“获取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>

第3个也是最后一个,编写验证谷歌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");
}