0

我正在按照此页面 上的说明实施不可见的 recaptcha。一切都很好,但我怎么知道它正在工作?有没有办法强制一个假的来测试它?

此外,上述页面上的文档不清楚,但有些地方有额外的代码来验证用户的“响应”(它是不可见的,所以我不确定这里的响应是什么) - 所以我需要添加额外的后端用不可见的生成令牌和我的密钥来命中这个端点的逻辑?reCaptcha

当用户在不可见的 recaptcha 上单击提交时会发生什么?API 中做了什么来返回令牌?令牌有什么用?siteverify api然后做什么来确定它的人?为什么在使用 reCAPTCHA V2(可见点击一)时不需要额外验证?

4

2 回答 2

2

是的你是。您需要了解隐形 reCaptcha 是一个包含多个步骤的过程,所有这些最终都会提供有关用户人性的最终响应。

简而言之,当用户提交表单(或执行任何您试图通过 Invisible reCaptcha 阻止机器人访问的操作)时,您会将您的公共站点密钥发送到您的后端,这将向 Google 启动验证负载。

在我非常基本的示例中,这是希望人类访问者单击以在我的网站上提交表单的按钮:

<button type="submit" class="g-recaptcha" data-sitekey="xxxxxxxx_obscured_xxxxxxxx" data-callback="onSubmit">Submit Form</button>

请注意按钮如何具有数据回调“onSubmit”,它在提交时运行这个小脚本:

 <script type="text/javascript">
  var onSubmit = function(response) {
    document.getElementById("simpleForm").submit(); // send response to your backend service
  };
</script>

在我的示例中,后端服务是一个普通的 PHP 脚本,旨在处理表单输入并将其存储在数据库中,这是棘手的部分。作为 POST 到后端的一部分,除了用户填写的表单字段之外,还有来自服务的响应(因为您可能会或可能不会在前端做很多事情,用户可以在响应之前操纵它发布到您的后端,此时谷歌的回应并不明确)

在您的后端,您需要获取来自 google 的 g-recaptcha-response 并使用您的私钥(不是表单上的那个)将其发布到验证 API,以获得人/机器人的判断你可以采取行动。这是一个用 PHP 编写并使用 cURL 访问 API 的简单示例:

$recaptcha_response = $_POST["g-recaptcha-response"];    
    $api_url = 'https://www.google.com/recaptcha/api/siteverify';
    $api_secret = 'zzzzzzz_OBSCURED_SECRET_KEY_zzzzzzzzzzz';
    $remoteip = '';

    $data = array('secret' => $api_secret, 'response' => $recaptcha_response);
    $options = array(
        'http' => array(
            'header' => "Content-type: application/x-www-form-urlencoded\r\n",
            'method' => 'POST',
            'content' => http_build_query($data)
        )
    );

    $context  = stream_context_create($options);
    $result = file_get_contents($api_url, false, $context);

    $captcha_response = json_decode($result, true);

    // at this point I have the definite verdict from google. Should I keep processing the form?.
    if ($captcha_response['success'] == true) {
      // I heart you, human. Keep going
      $captcha_error = 0;
    }

    else {
      // Damn robot, die a slow and painful death
      $captcha_error = 1;
    }

我根据 $captcha_error 做出最终决定(基本上 1 表示停止,0 表示继续处理)

如果您完全依赖于获得 g-recaptcha-response,那么您会让 Google 完成工作,然后忽略结果

于 2018-08-22T18:31:21.343 回答
2

After some testing it looks like you could just do the front end part. The data callback function is not called until google is sure you are a person, if google is not sure then it loads the "select which tiles have a thing in them" reCaptcha to be sure. Once the reCaptcha api is sure that it is a person, the data callback function is fired - at that time you can do further validation to ensure that the token you received during the callback is the one that google actually sent and not a bot trying to fool you by hitting your callback funct - so from there you do server side processing for further validation. Below is an example of a C# ashx handler - and ajax for the validation

function onTestSubmit(token) {  
        $.ajax({
            type: "POST",
            url: "testHandler.ashx",
            data: { token: token },
            success: function (response) {
                if (response == "True") {
                    //do stuff to submit form
                }
            }
        });            
    }

And the ashx

    public class testHandler : IHttpHandler {

    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";
        string token = context.Request.Form["token"];
        bool isCaptchaValid = ReCaptcha.Validate(token);

        context.Response.Write(isCaptchaValid.ToString());
    }


    public bool IsReusable {
        get {
            return false;
        }
    }

    }

    public class ReCaptcha
    {
        private static string URL = 
    "https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}";
        private static string SECRET = "shhhhhhhhhhhhhhSecretTOken"; 

        public bool Success { get; set; }
        public List<string> ErrorCodes { get; set; }

        public static bool Validate(string encodedResponse)
        {
        if (string.IsNullOrEmpty(encodedResponse)) return false;
        var client = new System.Net.WebClient();
        var googleReply = client.DownloadString(string.Format(URL, SECRET, encodedResponse));
        var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        var reCaptcha = serializer.Deserialize<ReCaptcha>(googleReply);
        return reCaptcha.Success;
    }
}
于 2017-09-22T23:27:25.480 回答