1

我之所以写,是因为这个网站上的任何问题都没有真正帮助我弄清楚为什么 reCaptcha 没有得到验证。我在我的页面上使用了两个 reCaptcha 的 V2 和 Invisible。不幸的是,我正在使用的项目非常古老,虽然它看起来像是 ASP.NET MVC,但我没有看到任何控制器或模型,所以我不知道它到底是用什么写的。我正在重建ASP.NET WebForms 中的项目,我有 reCaptcha 完美地工作。问题是我必须对旧网站使用 JavaScript,直到我发布新网站,这不会再过几个月。

这是我的表格:

<form id="form" action="?" method="post">
<fieldset>

    <div class="form-group">
        <div class="row">
            <div class="col-md-12">

                @* RECAPTCHA V2 WIDGET *@
                <div id="captcha2" class="g-recaptcha"
                     data-sitekey="6LdOZWkUAAAAAE1EhMyhMPF5IwM3lflaeyZ2VWaB"></div>
                <br />
                @* MESSAGE FROM RECAPTCHA *@
                <div id="msg" class="msg-error error"></div>
                <br>
                @* SUBMIT BUTTON FOR VALIDATION & RECAPTCHA *@
                <input id="submit" type="submit" name="buttonSubmit" class="btn btn-success btn-large"
                       value="Submit Information Request" />
                <input type="hidden" name="registerDate" value="@DateTime.Now" />
            </div>
        </div>
    </div>

    @* RECAPTCHA INVISIBLE WIDGET *@
    <div id="captchaI" class="g-recaptcha"
         data-sitekey="6LduaWkUAAAAAHp0EU5JXdTIszKR-g2AZfDqmLiv"
         data-callback="submit"
         data-size="invisible">
    </div>
</fieldset>

这是我的 JavaScript:

<script>
$('#submit').click(function () {
    //var obj =
    //{
    //    secret: "MY_PRIVATE_KEY",
    //    response: grecaptcha.getResponse()
    //};
    //var json = JSON.stringify(obj);
    //window.location = "https://www.google.com/recaptcha/api/siteverify?" + json;

    //var respJSON = '{"success": true | false, "challenge_ts": timestamp, "hostname":string}';
    //var respObj = JSON.parse(respJSON);
    //alert(respObj.success + "\n" + respObj.challenge_ts + "\n" + respObj.hostname);

    //--------------------------------------------------------------------

    alert("NO JSON\n" + grecaptcha.getResponse()); //I GET A HASHED RESPONSE

    var response = grecaptcha.getResponse();
    var stringy = JSON.stringify("STRINGIFY\n" + response);
    alert(stringy); //I GET A HASHED RESPONSE
    var parsy = JSON.parse("PARSED" + response);
    alert(parsed);  //I GET NOTHING

    //--------------------------------------------------------------------

    //var pk = 'MY_PRIVATE_KEY';
    //var url = "https://www.google.com/recaptcha/api/siteverify?secret=";
    //$.post(url,
    //    {
    //        "secret": pk,
    //        "response": "&response=" + response
    //    },
    //    function (response) {
    //        alert(response);
    //    });

    //alert(response);
    //JSON.stringify(response);
    //alert(response);
    //$('#msg').prepend(response);
    //if (!response) {
    //    $('#msg').text("No Response from Captcha.");
    //}
});

如您所见,我将 jQuery 与 JSON 结合使用。我尝试以多种方式从 reCaptcha 中提取响应,通常在 #msg div 中发布消息,但那里没有显示任何内容。

我知道Google Developers reCaptcha Guide 是怎么说的,但它对如何实际实现这一点帮助不大。请提供帮助,因为没有其他解决方案通过 siteverify 验证响应,使用由于代理控制而我无法使用的 PHP,或者在开发人员指南的情况下,没有帮助。

4

1 回答 1

1

看起来您正在尝试验证响应客户端。那是行不通的。Google 只会验证从您向他们注册的网址发送的响应。所以你需要验证响应服务器端。

首先,从小部件中获取哈希码

var captchaResponse = window.grecaptcha.getResponse();
if (captchaResponse === "") {
    alert("Please check \"I'm not a robot'\"");
    return;
}

接下来,将响应发送到您的服务器。

$.ajax({
    type: "POST",
    url: newRequestUrl,
    crossDomain: true,
    xhrFields: {
        withCredentials: false
    },
    data: {
        request: JSON.stringify(request),
        recaptchaResponse: recaptchaResponse
    },
    error: function (x1, x2, x3, x4) {
        alert("Error: unable to process request");
        window.grecaptcha.reset();
    },
    success: function (respose) {
        window.grecaptcha.reset();

        alert("Request received");
    }
});

出于我的目的,我需要发布跨域。您可能可以删除 crossDomain 参数。

然后,这是我处理帖子的终点。根据您的项目状态,您可能需要为此使用经典的 ASP.NET 表单。

    [AllowAnonymous]
    public JsonResult NewRequest(string request, string recaptchaResponse)
    {
        if (VerifyRecaptchaResponse(recaptchaResponse, Request.UserHostAddress) == false)
        {
            return Json(new { Error = "Invalid reCAPTCHA response" });
        }

        return Json(true);
    }

最后,验证响应。

    private static bool VerifyRecaptchaResponse(string recaptchaResponse, string remoteIp)
    {
        var recaptchaApiUrl = ConfigurationManager.AppSettings["recaptchaApiUrl"];
        var secret = ConfigurationManager.AppSettings["recaptchaSecretKey"];
        var postData = string.Format(CultureInfo.InvariantCulture, "&secret={0}&remoteip={1}&response={2}", secret, remoteIp, recaptchaResponse);
        var postDataAsBytes = Encoding.UTF8.GetBytes(postData);

        var request = WebRequest.Create(recaptchaApiUrl);
        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();

        var response = request.GetResponse();

        using (var stream = response.GetResponseStream())
        {
            if (stream == null) return false;

            using (var reader = new StreamReader(stream))
            {
                var serializer = new JavaScriptSerializer();
                var text = reader.ReadToEnd();
                var responseFromServer = serializer.DeserializeObject(text) as Dictionary<string, object>;
                if (responseFromServer == null) return false;
                if (responseFromServer.ContainsKey("success") == false) return false;
                if (responseFromServer["success"] is bool == false) return false;

                return (bool)responseFromServer["success"];
            }
        }
    }

希望这可以帮助。

于 2018-08-22T18:28:04.947 回答