【问题标题】:Google reCaptcha in Web API 2 c#Web API 2 c# 中的 Google reCaptcha
【发布时间】:2023-03-06 18:13:01
【问题描述】:

我有一个 ASP.NET Web API 2 项目。我正在尝试从表单中读取 Google Captcha。 我试过这个代码:

    public string Post(FoundingRequest model)
    {
        var response = Request["g-recaptcha-response"];
        string secretKey = "my key";
        var client = new WebClient();
        var result = client.DownloadString(
        $"https://www.google.com/recaptcha/api/siteverify?secret={secretKey}&response={response}");
        var obj = JObject.Parse(result);
        model.Captcha = (bool)obj.SelectToken("success");
        ....
    }

但我在第一行收到一个错误:

无法将 [] 索引应用于类型表达式 'HttpRequestMessage'

为什么?以及如何解决?谢谢

【问题讨论】:

    标签: c# asp.net-web-api asp.net-web-api2 recaptcha


    【解决方案1】:

    该方法的主体对我来说效果很好:

     const string secretKey = "YOUR KEY";
                string responseFromServer = "";
    
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://www.google.com/recaptcha/api/siteverify?secret=" + secretKey + "&response=" + response);
    
                using (WebResponse resp = req.GetResponse())
                using (Stream dataStream = resp.GetResponseStream())
                {
                    if (dataStream != null)
                    {
                        using (StreamReader reader = new StreamReader(dataStream))
                        {
                            // Read the content.
                            responseFromServer = reader.ReadToEnd();
                        }
                    }
                }
    
                dynamic jsonResponse = new JavaScriptSerializer().DeserializeObject(responseFromServer);
    
                return jsonResponse == null || bool.Parse(jsonResponse["success"].ToString());
    

    更新

    关于评论,可以在客户端查看

    var response = window.grecaptcha.getResponse()

    然后将这个变量传递给Web API

    这是我的客户端脚本的一部分:

          if (typeof window.grecaptcha != 'undefined') {
            var capResponse = window.grecaptcha.getResponse();
    
            if (!capResponse || capResponse.length === 0) {
                user.isCaptchaPassed = false;
                //alert("Captcha not Passed");
                return false;
            }
    
            user.gReCaptcha = capResponse;
        }
    

    “user”是之前创建的JS对象,通过JS传递给服务器。 (AJAX 调用)

    【讨论】:

    • 问题出在这一行:var response = Request["g-recaptcha-response"];
    • 检查更新。它应该适用于 JS 和 Web API
    【解决方案2】:

    这就是我的做法。我不使用挑战,所以我没有打扰 试图弄清楚为什么它没有正确转换为 DateTime 。 也许其他人已经解决了这个问题。

       public class ReCaptchaResponse
            {
                public bool Success;
                public string ChallengeTs;
                public string Hostname;
                public object[] ErrorCodes;
            }
    
            [HttpPost]
            [Route("captcha")]
            public bool Captcha([FromBody] string token)
            {
                bool isHuman = true;
    
                try
                {
                    string secretKey = ConfigurationManager.AppSettings["reCaptchaPrivateKey"];
                    Uri uri = new Uri("https://www.google.com/recaptcha/api/siteverify" +
                                      $"?secret={secretKey}&response={token}");
                    HttpWebRequest request = WebRequest.CreateHttp(uri);
                    request.Method = "POST";
                    request.ContentType = "application/x-www-form-urlencoded";
                    request.ContentLength = 0;
                    HttpWebResponse response = (HttpWebResponse) request.GetResponse();
                    Stream responseStream = response.GetResponseStream();
                    StreamReader streamReader = new StreamReader(responseStream);
                    string result = streamReader.ReadToEnd();
                    ReCaptchaResponse reCaptchaResponse = JsonConvert.DeserializeObject<ReCaptchaResponse>(result);
                    isHuman = reCaptchaResponse.Success;
                }
                catch (Exception ex)
                {
                    Trace.WriteLine("reCaptcha error: " + ex);
                }
    
                return isHuman;
            }
    

    【讨论】:

      【解决方案3】:

      我找到了答案,我创建了一个具有特定名称的隐藏输入,并在 Captcha 回调中更新了它的值。代码:

         <input type="hidden" value="" id="recaptcha" name="recaptcha" />
         <div class="g-recaptcha" data-callback="imNotARobot" data-sitekey="key"></div>
      

      而 Javascript 是:

      <script type="text/javascript">
          var imNotARobot = function () {
             $("#recaptcha").val(grecaptcha.getResponse());
          };
      </script>
      

      服务器端:

      public string Recaptcha { get; set; }
      

      模型绑定器完成所有工作。

      【讨论】:

        【解决方案4】:

        我假设这个请求来自一个表单,更改这个:

        var response = Request["g-recaptcha-response"];
        

        至此:

        var response = Request.Form["g-Recaptcha-Response"];
        

        也改变这个:

        var result = client.DownloadString($"https://www.google.com/recaptcha/api/siteverify?secret={secretKey}&response={response}");
        

        至此:

        var result = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secretKey, response));
        

        【讨论】:

        • 请再次阅读问题。问题在于: var response = Request["g-recaptcha-response"];问题中提到的错误消息的第一行
        • Web Api 2 请求中没有表单
        • 验证码在哪里?在 MVC 页面上?您需要在 MVC 控制器中验证 ReCaptcha,然后调用 API。
        • 它在纯 html 和 javascript 上。没有服务器端
        • 它不会那样工作。您需要在 Web 应用程序中执行服务器端检查。由于 API 无法从标记中收集所需的其他信息,例如站点密钥。
        猜你喜欢
        • 2019-05-11
        • 1970-01-01
        • 1970-01-01
        • 2022-01-19
        • 1970-01-01
        • 2021-10-20
        • 2016-10-21
        • 2020-12-12
        • 2016-05-31
        相关资源
        最近更新 更多