ASP.NET MVC के लिए reCaptcha कैसे लागू करें? [बन्द है]


80

मैं ASP.NET MVC और C # में reCaptcha कैसे लागू करूं?


यदि आप ASP.NET वेब फॉर्म्स में कंबाइंड Google reCAPTCHA v2 & v3 का नवीनतम समाधान देख रहे हैं, तो यह देखें कि डेमो techtolia.com/Recaptcha
Leo

जवाबों:


83

कुछ महान उदाहरण हैं:

इसमें पहले भी कवर किया गया है इस स्टैक ओवरफ्लो प्रश्न यह

MVC 4 और 5 के लिए NuGet Google reCAPTCHA V2 है


त्वरित उत्तर के लिए धन्यवाद। मेरा एक सवाल है, किसने बनाया Recaptcha.dll? Google टीम?
xport

4
ReCaptcha Carnegie Mellon University के एक प्रोफेसर द्वारा मुझे विश्वास कराया गया था ।
जॉर्ज स्टॉकर

1
तीसरे वाले ( dotnetcurry.com/ShowArticle.aspx?ID=611 ) ने मेरे लिए बहुत अच्छा काम किया।
सैलरी

मैं Dirik Whittaker का कोड उपयोग कर रहा हूं। Microsoft.Web.Helpers को संदर्भित किया जाता है, लेकिन मुझे इस लाइन पर एक नामस्थान नाम मिला 'Recaptcha' नहीं मिली: var captchaValidtor = new Recaptcha.RecaptchaValidator
M3NTA7

@ M3NTA7 आप इस टिप्पणी की तुलना में एक प्रश्न को और अधिक गहराई में ले जाना चाहते हैं।
जॉर्ज स्टॉकर

33

मैंने एक प्रोजेक्ट में reCaptcha को जोड़ा है जो मैं वर्तमान में काम कर रहा हूं। मुझे AJAX API का उपयोग करने की आवश्यकता थी क्योंकि reCaptcha तत्व को गतिशील रूप से पृष्ठ में लोड किया गया था। मुझे कोई मौजूदा नियंत्रण नहीं मिला और एपीआई सरल है इसलिए मैंने अपना खुद का बनाया।

अगर कोई इसे उपयोगी पाता है तो मैं अपना कोड यहाँ पोस्ट करूँगा।

1: मास्टर पेज हेडर में स्क्रिप्ट टैग जोड़ें

<script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>

2: web.config में अपनी कुंजियाँ जोड़ें

<appSettings>
    <add key="ReCaptcha.PrivateKey" value="[key here]" />
    <add key="ReCaptcha.PublicKey" value="[key here]" />
</appSettings>

3: एक्शन अटेंशन और एचटीएमएल हेल्पर एक्सटेंशन बनाएं

namespace [Your chosen namespace].ReCaptcha
{
    public enum Theme { Red, White, BlackGlass, Clean }

    [Serializable]
    public class InvalidKeyException : ApplicationException
    {
        public InvalidKeyException() { }
        public InvalidKeyException(string message) : base(message) { }
        public InvalidKeyException(string message, Exception inner) : base(message, inner) { }
    }

    public class ReCaptchaAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var userIP = filterContext.RequestContext.HttpContext.Request.UserHostAddress;

            var privateKey = ConfigurationManager.AppSettings.GetString("ReCaptcha.PrivateKey", "");

            if (string.IsNullOrWhiteSpace(privateKey))
                throw new InvalidKeyException("ReCaptcha.PrivateKey missing from appSettings");

            var postData = string.Format("&privatekey={0}&remoteip={1}&challenge={2}&response={3}",
                                         privateKey,
                                         userIP,
                                         filterContext.RequestContext.HttpContext.Request.Form["recaptcha_challenge_field"],
                                         filterContext.RequestContext.HttpContext.Request.Form["recaptcha_response_field"]);

            var postDataAsBytes = Encoding.UTF8.GetBytes(postData);

            // Create web request
            var request = WebRequest.Create("http://www.google.com/recaptcha/api/verify");
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = postDataAsBytes.Length;
            var dataStream = request.GetRequestStream();
            dataStream.Write(postDataAsBytes, 0, postDataAsBytes.Length);
            dataStream.Close();

            // Get the response.
            var response = request.GetResponse();

            using (dataStream = response.GetResponseStream())
            {
                using (var reader = new StreamReader(dataStream))
                {
                    var responseFromServer = reader.ReadToEnd();

                    if (!responseFromServer.StartsWith("true"))
                        ((Controller)filterContext.Controller).ModelState.AddModelError("ReCaptcha", "Captcha words typed incorrectly");
                }
            }
        }
    }

    public static class HtmlHelperExtensions
    {
        public static MvcHtmlString GenerateCaptcha(this HtmlHelper helper, Theme theme, string callBack = null)
        {
            const string htmlInjectString = @"<div id=""recaptcha_div""></div>
<script type=""text/javascript"">
    Recaptcha.create(""{0}"", ""recaptcha_div"", {{ theme: ""{1}"" {2}}});
</script>";

            var publicKey = ConfigurationManager.AppSettings.GetString("ReCaptcha.PublicKey", "");

            if (string.IsNullOrWhiteSpace(publicKey))
                throw new InvalidKeyException("ReCaptcha.PublicKey missing from appSettings");

            if (!string.IsNullOrWhiteSpace(callBack))
                callBack = string.Concat(", callback: ", callBack);

            var html = string.Format(htmlInjectString, publicKey, theme.ToString().ToLower(), callBack);
            return MvcHtmlString.Create(html);
        }
    }
}

4: कैप्चा को अपने विचार में जोड़ें

@using (Html.BeginForm("MyAction", "MyController"))
{
   @Html.TextBox("EmailAddress", Model.EmailAddress)
   @Html.GenerateCaptcha(Theme.White)
   <input type="submit" value="Submit" />
}

5: अपनी कार्रवाई में विशेषता जोड़ें

[HttpPost]
[ReCaptcha]
public ActionResult MyAction(MyModel model)
{
   if (!ModelState.IsValid) // Will have a Model Error "ReCaptcha" if the user input is incorrect
      return Json(new { capthcaInvalid = true });

   ... other stuff ...
}

6: ध्यान दें कि आपको प्रत्येक पोस्ट के बाद कैप्चा को फिर से लोड करना होगा, भले ही वह वैध हो और फॉर्म का दूसरा हिस्सा अमान्य था। उपयोगRecaptcha.reload();


क्या इस कोड के साथ 5 असफल लॉगिन के बाद केवल ReCaptcha को एनोटेट करना संभव है?
रोब

2
यदि आप इस समाधान को कार्यान्वित कर रहे हैं, तो इस बात पर ध्यान दें कि नया API url है: google.com/recaptcha/api/siteverify ( स्रोत )
Axel Prieto

14

मेरे लिए काम करने का सरल और पूर्ण समाधान । ASP.NET MVC 4 और 5 का समर्थन करता है (ASP.NET 4.0, 4.5 और 4.5.1 का समर्थन करता है)

चरण 1: " इंस्टॉल-पैकेज reCAPTCH.MVC " द्वारा NuGet पैकेज स्थापित करें

चरण 2: अपने सार्वजनिक और निजी कुंजी को अपने वेब.कॉन्फ़िग फ़ाइल में एप्लेटिंग अनुभाग में जोड़ें

<appSettings>
    <add key="ReCaptchaPrivateKey" value=" -- PRIVATE_KEY -- " />
    <add key="ReCaptchaPublicKey" value=" -- PUBLIC KEY -- " />
</appSettings>  

आप https://www.google.com/recaptcha/intro/index.html पर अपनी साइट के लिए एक एपीआई कुंजी जोड़ी बना सकते हैं और पृष्ठ के शीर्ष पर Get reCAPTCHA पर क्लिक कर सकते हैं

चरण 3: reCaptcha को शामिल करने के लिए अपने फ़ॉर्म को संशोधित करें

@using reCAPTCHA.MVC
@using (Html.BeginForm())
{
    @Html.Recaptcha()
    @Html.ValidationMessage("ReCaptcha")
    <input type="submit" value="Register" />
}

चरण 4 : कंट्रोलर एक्शन लागू करें जो फॉर्म सबमिशन और कैप्चा वेलिडेशन को हैंडल करेगा

[CaptchaValidator(
PrivateKey = "your private reCaptcha Google Key",
ErrorMessage = "Invalid input captcha.",
RequiredMessage = "The captcha field is required.")]
public ActionResult MyAction(myVM model)
{
    if (ModelState.IsValid) //this will take care of captcha
    {
    }
}

या

public ActionResult MyAction(myVM model, bool captchaValid)
{
    if (captchaValid) //manually check for captchaValid 
    {
    }
}

दुर्भाग्य से इसकी वजह से एक ही पृष्ठ में दो अलग-अलग रूपों में इसका उपयोग करना संभव नहीं है Uncaught Error: ReCAPTCHA placeholder element must be empty
Alisson

1
जैसा कि reCaptcha कुंजियों के लिए web.config का उपयोग करता है, आपको आपूर्ति करने की आवश्यकता नहीं है PrivateKey = "your private reCaptcha Google Key"। यह बहुत आसान है जब आपके पास अलग-अलग वातावरणों के लिए अलग-अलग चाबियाँ हैं
लाल

13

MVC 5 के लिए एक async संस्करण (यानी ActionFilterAttribute से बचने के लिए, जो MVC 6 तक async नहीं है) और reCAPTCHA 2

ExampleController.cs

public class HomeController : Controller
{
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> ContactSubmit(
        [Bind(Include = "FromName, FromEmail, FromPhone, Message, ContactId")]
        ContactViewModel model)
    {
        if (!await RecaptchaServices.Validate(Request))
        {
            ModelState.AddModelError(string.Empty, "You have not confirmed that you are not a robot");
        }
        if (ModelState.IsValid)
        {
           ...

ExampleView.cshtml

@model MyMvcApp.Models.ContactViewModel

@*This is assuming the master layout places the styles section within the head tags*@
@section Styles {
    @Styles.Render("~/Content/ContactPage.css")
    <script src='https://www.google.com/recaptcha/api.js'></script>
}

@using (Html.BeginForm("ContactSubmit", "Home",FormMethod.Post, new { id = "contact-form" }))
{
    @Html.AntiForgeryToken()
    ...
    <div class="form-group">
      @Html.LabelFor(m => m.Message) 
      @Html.TextAreaFor(m => m.Message, new { @class = "form-control", @cols = "40", @rows = "3" })
      @Html.ValidationMessageFor(m => m.Message)
    </div>

    <div class="row">
      <div class="g-recaptcha" data-sitekey='@System.Configuration.ConfigurationManager.AppSettings["RecaptchaClientKey"]'></div>
    </div>

    <div class="row">
      <input type="submit" id="submit-button" class="btn btn-default" value="Send Your Message" />
    </div>
}

RecaptchaServices.cs

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web;
using System.Configuration;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using System.Runtime.Serialization;

namespace MyMvcApp.Services
{
    public class RecaptchaServices
    {
        //ActionFilterAttribute has no async for MVC 5 therefore not using as an actionfilter attribute - needs revisiting in MVC 6
        internal static async Task<bool> Validate(HttpRequestBase request)
        {
            string recaptchaResponse = request.Form["g-recaptcha-response"];
            if (string.IsNullOrEmpty(recaptchaResponse))
            {
                return false;
            }
            using (var client = new HttpClient { BaseAddress = new Uri("https://www.google.com") })
            {
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                var content = new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair<string, string>("secret", ConfigurationManager.AppSettings["RecaptchaSecret"]),
                    new KeyValuePair<string, string>("response", recaptchaResponse),
                    new KeyValuePair<string, string>("remoteip", request.UserHostAddress)
                });
                var result = await client.PostAsync("/recaptcha/api/siteverify", content);
                result.EnsureSuccessStatusCode();
                string jsonString = await result.Content.ReadAsStringAsync();
                var response = JsonConvert.DeserializeObject<RecaptchaResponse>(jsonString);
                return response.Success;
            }
        }

        [DataContract]
        internal class RecaptchaResponse
        {
            [DataMember(Name = "success")]
            public bool Success { get; set; }
            [DataMember(Name = "challenge_ts")]
            public DateTime ChallengeTimeStamp { get; set; }
            [DataMember(Name = "hostname")]
            public string Hostname { get; set; }
            [DataMember(Name = "error-codes")]
            public IEnumerable<string> ErrorCodes { get; set; }
        }

    }
}

web.config

<configuration>
  <appSettings>
    <!--recaptcha-->
    <add key="RecaptchaSecret" value="***secret key from https://developers.google.com/recaptcha***" />
    <add key="RecaptchaClientKey" value="***client key from https://developers.google.com/recaptcha***" />
  </appSettings>
</configuration>

यह मेरे लिए काम किया! ... MVC v5, recaptcha v2 ~ 2018
MTAdmin

8

चरण 1: ग्राहक साइट एकीकरण

</head>अपने HTML टेम्पलेट पर बंद टैग से पहले इस स्निपेट को चिपकाएँ :

<script src='https://www.google.com/recaptcha/api.js'></script>

इस स्निपेट को उस स्थान पर चिपकाएँ <form>जहाँ आप चाहते हैं कि reCAPTCHA विजेट दिखाई दे:

<div class="g-recaptcha" data-sitekey="your-site-key"></div>

चरण 2: सर्वर साइट एकीकरण

जब आपके उपयोगकर्ता उस फ़ॉर्म को जमा करते हैं जहाँ आपने reCAPTCHA को एकीकृत किया है, तो आपको "g-recaptcha-response" नाम के साथ पेलोड स्ट्रिंग का हिस्सा मिलेगा। यह जाँचने के लिए कि क्या Google ने उस उपयोगकर्ता को सत्यापित किया है, इन मापदंडों के साथ एक POST अनुरोध भेजें:

URL: https://www.google.com/recaptcha/api/siteverify

गुप्त: आपकी गुप्त कुंजी

प्रतिक्रिया: 'g-recaptcha-response' का मान।

अब आपके MVC ऐप की कार्रवाई में:

// return ActionResult if you want
    public string RecaptchaWork()
    {
        // Get recaptcha value
        var r = Request.Params["g-recaptcha-response"];
        // ... validate null or empty value if you want
        // then
        // make a request to recaptcha api
        using (var wc = new WebClient())
        {
            var validateString = string.Format(
                "https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}",
               "your_secret_key",    // secret recaptcha key
               r); // recaptcha value
             // Get result of recaptcha
            var recaptcha_result = wc.DownloadString(validateString);
            // Just check if request make by user or bot
            if (recaptcha_result.ToLower().Contains("false"))
            {
                 return "recaptcha false";
            }
        }
        // Do your work if request send from human :)
    }

7

मैंने निम्नलिखित तरीके से ReCaptcha को सफलतापूर्वक लागू किया है।
नोट: यह VB में है, लेकिन आसानी से परिवर्तित किया जा सकता है

1] सबसे पहले reCaptcha पुस्तकालय की एक प्रति को पकड़ो

2] फिर एक कस्टम ReCaptcha HTML हेल्पर का निर्माण करें

    ''# fix SO code coloring issue.
    <Extension()>
    Public Function reCaptcha(ByVal htmlHelper As HtmlHelper) As MvcHtmlString
        Dim captchaControl = New Recaptcha.RecaptchaControl With {.ID = "recaptcha",
                                                                  .Theme = "clean",
                                                                  .PublicKey = "XXXXXX",
                                                                  .PrivateKey = "XXXXXX"}
        Dim htmlWriter = New HtmlTextWriter(New IO.StringWriter)
        captchaControl.RenderControl(htmlWriter)
        Return MvcHtmlString.Create(htmlWriter.InnerWriter.ToString)
    End Function

3] यहाँ से आपको एक पुन: उपयोग करने योग्य सर्वर साइड सत्यापनकर्ता की आवश्यकता है

Public Class ValidateCaptchaAttribute : Inherits ActionFilterAttribute
    Private Const CHALLENGE_FIELD_KEY As String = "recaptcha_challenge_field"
    Private Const RESPONSE_FIELD_KEY As String = "recaptcha_response_field"

    Public Overrides Sub OnActionExecuting(ByVal filterContext As ActionExecutingContext)

        If IsNothing(filterContext.HttpContext.Request.Form(CHALLENGE_FIELD_KEY)) Then
            ''# this will push the result value into a parameter in our Action
            filterContext.ActionParameters("CaptchaIsValid") = True
            Return
        End If

        Dim captchaChallengeValue = filterContext.HttpContext.Request.Form(CHALLENGE_FIELD_KEY)
        Dim captchaResponseValue = filterContext.HttpContext.Request.Form(RESPONSE_FIELD_KEY)

        Dim captchaValidtor = New RecaptchaValidator() With {.PrivateKey = "xxxxx",
                                                                       .RemoteIP = filterContext.HttpContext.Request.UserHostAddress,
                                                                       .Challenge = captchaChallengeValue,
                                                                       .Response = captchaResponseValue}

        Dim recaptchaResponse = captchaValidtor.Validate()

        ''# this will push the result value into a parameter in our Action
        filterContext.ActionParameters("CaptchaIsValid") = recaptchaResponse.IsValid

        MyBase.OnActionExecuting(filterContext)
    End Sub

इस पंक्ति के ऊपर पुन: प्रयोज्य ** वन टाइम ** कोड है


इस पंक्ति के नीचे यह आसान है कि कैसे दोबारा से लागू करना आसान है

अब जब आपके पास अपना पुन: उपयोग करने योग्य कोड है ... आपको केवल अपने दृश्य में कैप्चा जोड़ना होगा।

<%: Html.reCaptcha %>

और जब आप फॉर्म को अपने कंट्रोलर को पोस्ट करते हैं ...

    ''# Fix SO code coloring issues
    <ValidateCaptcha()>
    <AcceptVerbs(HttpVerbs.Post)>
    Function Add(ByVal CaptchaIsValid As Boolean, ByVal [event] As Domain.Event) As ActionResult


        If Not CaptchaIsValid Then ModelState.AddModelError("recaptcha", "*")


        '#' Validate the ModelState and submit the data.
        If ModelState.IsValid Then
            ''# Post the form
        Else
            ''# Return View([event])
        End If
    End Function

नोट: यह VB में है लेकिन इसे आसानी से C #
चेस फ्लोरल

1
समाधान को विस्तृत करने के लिए आपका बहुत-बहुत धन्यवाद। यह बहुत विस्तृत उत्तर है। मुझे यह पसंद है।
xport

1
जोएल के सबसे हालिया ब्लॉग के अनुसार, StackOverflow के निर्माता चाहते हैं कि यह केवल अन्य साइटों पर उपयोगकर्ताओं को पुनर्निर्देशित करने के बजाय एक विकी रिपॉजिटरी हो । किसी साइट पर आपको भेजने से आज आपके सवाल का जवाब मिल सकता है, लेकिन अगले साल उस बाहरी पेज के नीचे आने पर किसी और की समस्या का समाधान नहीं होगा। यहां सही उत्तर पोस्ट करने से भविष्य के चाहने वालों को मदद मिलेगी। मेरा मानना ​​है कि किसी प्रश्न का उत्तर देने का यह सही तरीका है।
चेस फ्लोरल

भाषा अंतर को छोड़कर devlicio.us/blogs/derik_whittaker/archive/2008/12/02/… के लगभग समान दिखता है ..
gmail उपयोगकर्ता

2

मैगपाई के उत्तर का विस्तार, यहां एक्शन फिल्टर के लिए कोड है जो मैं अपने प्रोजेक्ट में उपयोग करता हूं।

यह ASP Core RC2 के साथ काम करता है!

public class ReCaptchaAttribute : ActionFilterAttribute
{
    private readonly string CAPTCHA_URL = "https://www.google.com/recaptcha/api/siteverify";
    private readonly string SECRET = "your_secret";

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        try
        {
            // Get recaptcha value
            var captchaResponse = filterContext.HttpContext.Request.Form["g-recaptcha-response"];

            using (var client = new HttpClient())
            {
                var values = new Dictionary<string, string>
                {
                    { "secret", SECRET },
                    { "response", captchaResponse },
                    { "remoteip", filterContext.HttpContext.Request.HttpContext.Connection.RemoteIpAddress.ToString() }
                };


                var content = new FormUrlEncodedContent(values);

                var result = client.PostAsync(CAPTCHA_URL, content).Result;

                if (result.IsSuccessStatusCode)
                {
                    string responseString = result.Content.ReadAsStringAsync().Result;

                    var captchaResult = JsonConvert.DeserializeObject<CaptchaResponseViewModel>(responseString);

                    if (!captchaResult.Success)
                    {
                        ((Controller)filterContext.Controller).ModelState.AddModelError("ReCaptcha", "Captcha not solved");
                    }
                } else
                {
                    ((Controller)filterContext.Controller).ModelState.AddModelError("ReCaptcha", "Captcha error");
                }
            }

        }
        catch (System.Exception)
        {
            ((Controller)filterContext.Controller).ModelState.AddModelError("ReCaptcha", "Unknown error");
        }
    }
}

और अपने कोड में इसका उपयोग करें

[ReCaptcha]
    public IActionResult Authenticate()
    {

        if (!ModelState.IsValid)
        {
            return View(
                "Login",
                new ReturnUrlViewModel
                {
                    ReturnUrl = Request.Query["returnurl"],
                    IsError = true,
                    Error = "Wrong reCAPTCHA"
                }
            );
        }

1

किसी और को देखने के लिए, यहां चरणों का एक सभ्य सेट है। http://forums.asp.net/t/1678976.aspx/1

मैन्युअल रूप से OnActionExecuting () में अपनी कुंजी जोड़ने के लिए मत भूलना जैसे मैंने किया था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.