Java Google reCAPTCHA:如何在服务器端获取用户响应和验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27297067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 04:08:23  来源:igfitidea点击:

Google reCAPTCHA: how to get user response and validate in the server side

javajavascriptrecaptcha

提问by curious1

I am doing a Java (JSP + Servlet) web application (I understand that this question is technology-independent). I hope to use the latest Goolge reCAPTCHA service.

我正在做一个 Java (JSP + Servlet) web 应用程序(我知道这个问题与技术无关)。我希望使用最新的Goolge reCAPTCHA 服务。

I am playing with a Goolge reCAPTCHA example found here:

我正在使用此处找到的 Goolge reCAPTCHA 示例:

https://developers.google.com/recaptcha/docs/display#config

https://developers.google.com/recaptcha/docs/display#config

<html>
  <head>
    <title>reCAPTCHA demo: Simple page</title>
     <script src="https://www.google.com/recaptcha/api.js" async defer></script>
  </head>
  <body>
    <form action="?" method="POST">
      <div class="g-recaptcha" data-sitekey="my_site_key"></div>
      <br/>
      <input type="submit" value="Submit">
    </form>
  </body>
</html>

I am able to see the displayed recaptcha image as follows:

我能够看到显示的recaptcha图像如下:

enter image description here

在此处输入图片说明

When I check "I'm not a robot", I get the following:

当我检查“我不是机器人”时,我得到以下信息:

enter image description here

在此处输入图片说明

As you can see, there is a Verify button and based on my tests, user response is sent to Google for verification.

如您所见,有一个验证按钮,根据我的测试,用户响应会发送给 Google 进行验证。

How can I get the user response so that I can verify user response in my own backend code (as suggested by Google at https://developers.google.com/recaptcha/docs/verify).

我如何获得用户响应,以便我可以在我自己的后端代码中验证用户响应(如 Google 在https://developers.google.com/recaptcha/docs/verify建议的那样)。

g-recaptcha-response POST parameter when the user submits the form on your site

On the server side, I can, by clicking on the "Submit" button, get user input from parameter "g-recaptcha-response" only when a user is verified successfully with Google first. Otherwise, "g-recaptcha-response" is blank on the server side. This means that I can do server-side verification only after the client-side's verification success. If so, what is the point of doing another verification on the server-side, which is the option provided by Google reCAPTHA?

在服务器端,只有当用户首先通过 Google 成功验证时,我才能通过单击“提交”按钮从参数“g-recaptcha-response”中获取用户输入。否则,服务器端的“g-recaptcha-response”为空白。这意味着只有在客户端验证成功后才能进行服务器端验证。如果是这样,在服务器端进行另一次验证有什么意义,这是 Google reCAPTHA 提供的选项?

Do I missing anything?

我错过了什么吗?

采纳答案by TheRueger

The cool thing about the new Google Recaptcha is that the validation is now completely encapsulated in the widget. That means, that the widget will take care of asking questions, validating responses all the way till it determines that a user is actually a human, only then you get a g-recaptcha-responsevalue.

新的 Google Recaptcha 很酷的一点是验证现在完全封装在小部件中。这意味着,小部件将负责提出问题,一直验证响应,直到确定用户实际上是人类,然后您才能获得g-recaptcha-response值。

But that does not keep your site safe from HTTP client request forgery.

但这并不能保护您的站点免受 HTTP 客户端请求伪造的影响。

Anyone with HTTP POST knowledge could put random data inside of the g-recaptcha-responseform field, and foll your site to make it think that this field was provided by the google widget. So you haveto validate this token.

任何具有 HTTP POST 知识的人都可以将随机数据放入g-recaptcha-response表单字段中,并关注您的站点,使其认为该字段是由 google 小部件提供的。所以你必须验证这个令牌。

In human speech it would be like,

在人类语言中,它会是这样的,

  • Your Server: Hey Google, there's a dude that tells me that he's not a robot. He says that you already verified that he's a human, and he told me to give you this token as a proof of that.
  • Google: Hmm... let me check this token... yes I remember this dude I gave himthis token... yeah he's made of flesh and bone let him through.
  • Your Server: Hey Google, there's another dude that tells me that he's a human. He also gave me a token.
  • Google: Hmm... it's the same token you gave me last time... I'm pretty sure this guy is trying to fool you. Tell him to get off your site.
  • 你的服务器:嘿谷歌,有一个家伙告诉我他不是机器人。他说你已经证实他是人类,他让我给你这个令牌作为证明。
  • 谷歌:嗯……让我检查一下这个令牌……是的,我记得这个家伙我给了他这个令牌……是的,他是骨肉做的,让他通过。
  • 你的服务器:嘿谷歌,还有一个家伙告诉我他是一个人。他还给了我一个令牌。
  • 谷歌:嗯……这和你上次给我的标志是一样的……我很确定这家伙是想骗你。告诉他离开你的网站。

Validating the response is really easy. Just make a GET Request to

验证响应非常简单。只需发出 GET 请求即可

https://www.google.com/recaptcha/api/siteverify?secret=your_secret&response=response_string&remoteip=user_ip_address

https://www.google.com/recaptcha/api/siteverify?secret=your_secret&response=response_string&remoteip=user_ip_address

And replace the response_stringwith the value that you earlier got by the g-recaptcha-responsefield.

并将response_string替换为您之前通过g-recaptcha-response字段获得的值。

You will get a JSON Response with a successfield.

您将获得带有成功字段的 JSON 响应。

More information here:https://developers.google.com/recaptcha/docs/verify

更多信息请访问:https : //developers.google.com/recaptcha/docs/verify

回答by Pravin Sharma

Hi curious you can validate your google recaptcha at client side also100% workfor me to verify your google recaptcha just see below code
This code at the html body:

嗨,好奇您可以在客户端验证您的谷歌验证码,也可以100%为我验证您的谷歌验证
码,只需查看下面的代码 html 正文中的此代码:

 <div class="g-recaptcha" id="rcaptcha" style="margin-left: 90px;" data-sitekey="my_key"></div>
 <span id="captcha" style="margin-left:100px;color:red" />

This code put at head section on call get_action(this)method form button:

此代码放在调用get_action(this)方法表单按钮的头部部分:

function get_action(form) {

var v = grecaptcha.getResponse();
if(v.length == 0)
{
    document.getElementById('captcha').innerHTML="You can't leave Captcha Code empty";
    return false;
}
 if(v.length != 0)
 {
    document.getElementById('captcha').innerHTML="Captcha completed";
    return true; 
 }
}

回答by Rob Kraft

A method I use in my login servlet to verify reCaptcha responses. Uses classes from the java.json package. Returns the API response in a JsonObject.

我在登录 servlet 中使用的一种方法来验证 reCaptcha 响应。使用 java.json 包中的类。以 JsonObject 形式返回 API 响应。

Check the success field for true or false

检查成功字段是否为真

private JsonObject validateCaptcha(String secret, String response, String remoteip)
{
    JsonObject jsonObject = null;
    URLConnection connection = null;
    InputStream is = null;
    String charset = java.nio.charset.StandardCharsets.UTF_8.name();

    String url = "https://www.google.com/recaptcha/api/siteverify";
    try {            
        String query = String.format("secret=%s&response=%s&remoteip=%s", 
        URLEncoder.encode(secret, charset), 
        URLEncoder.encode(response, charset),
        URLEncoder.encode(remoteip, charset));

        connection = new URL(url + "?" + query).openConnection();
        is = connection.getInputStream();
        JsonReader rdr = Json.createReader(is);
        jsonObject = rdr.readObject();

    } catch (IOException ex) {
        Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
    }
    finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
            }

        }
    }
    return jsonObject;
}

回答by sandeep kumar

Here is complete demo code to understand client side and server side process. you can copy paste it and just replace google site keyand google secret key.

这是完整的演示代码,用于了解客户端和服务器端流程。您可以复制粘贴它,只需替换谷歌站点密钥谷歌密钥。

<?php 
if(!empty($_REQUEST))
{
      //  echo '<pre>'; print_r($_REQUEST); die('END');
        $post = [
            'secret' => 'Your Secret key',
            'response' => $_REQUEST['g-recaptcha-response'],
        ];
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL,"https://www.google.com/recaptcha/api/siteverify");
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        $server_output = curl_exec($ch);

        curl_close ($ch);
        echo '<pre>'; print_r($server_output); die('ss');
}
?>
<html>
  <head>
    <title>reCAPTCHA demo: Explicit render for multiple widgets</title>
    <script type="text/javascript">
      var site_key = 'Your Site key';
      var verifyCallback = function(response) {
        alert(response);
      };
      var widgetId1;
      var widgetId2;
      var onloadCallback = function() {
        // Renders the HTML element with id 'example1' as a reCAPTCHA widget.
        // The id of the reCAPTCHA widget is assigned to 'widgetId1'.
        widgetId1 = grecaptcha.render('example1', {
          'sitekey' : site_key,
          'theme' : 'light'
        });
        widgetId2 = grecaptcha.render(document.getElementById('example2'), {
          'sitekey' : site_key
        });
        grecaptcha.render('example3', {
          'sitekey' : site_key,
          'callback' : verifyCallback,
          'theme' : 'dark'
        });
      };
    </script>
  </head>
  <body>
    <!-- The g-recaptcha-response string displays in an alert message upon submit. -->
    <form action="javascript:alert(grecaptcha.getResponse(widgetId1));">
      <div id="example1"></div>
      <br>
      <input type="submit" value="getResponse">
    </form>
    <br>
    <!-- Resets reCAPTCHA widgetId2 upon submit. -->
    <form action="javascript:grecaptcha.reset(widgetId2);">
      <div id="example2"></div>
      <br>
      <input type="submit" value="reset">
    </form>
    <br>
    <!-- POSTs back to the page's URL upon submit with a g-recaptcha-response POST parameter. -->
    <form action="?" method="POST">
      <div id="example3"></div>
      <br>
      <input type="submit" value="Submit">
    </form>
    <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
        async defer>
    </script>
  </body>
</html>