Google reCaptcha 不工作

Google reCaptcha Not Working

我写这篇文章是因为这个网站上的任何问题都没有真正帮助我弄清楚为什么 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 由于机构控制我无法使用,或者在开发人员指南的情况下,没有帮助。

您似乎在尝试验证响应客户端。那行不通的。 Google 将仅验证您向他们注册的 url 发送的回复。所以你需要验证响应服务器端。

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

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");
    }
});

出于我的目的,我需要 post 跨域。您或许可以删除 crossDomain 参数。

那么,这是我处理 post 的终点。根据您的项目状态,您可能需要为此使用经典的 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"];
            }
        }
    }

希望对您有所帮助。