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

cur*_*us1 29 javascript java recaptcha

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

我正在玩这里找到的Goolge reCAPTCHA示例:

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>
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

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

在此输入图像描述

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

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

g-recaptcha-response POST parameter when the user submits the form on your site
Run Code Online (Sandbox Code Playgroud)

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

我错过了什么吗?

The*_*ger 79

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

但这并不能保证您的网站免受HTTP客户端请求伪造.

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

在人类的演讲中,它会是,

  • 你的服务器:嘿谷歌,有一个家伙告诉我他不是机器人.他说你已经证实他是一个人,他告诉我给你这个标记作为证明.
  • 谷歌:嗯...让我检查这个标记......是的我记得这个家伙我给了他这个标记......是的,他是用肉和骨头让他通过的.
  • 你的服务器:嘿谷歌,还有另一个家伙告诉我他是一个人.他还给了我一个代币.
  • 谷歌:嗯......这和你上次给我的一样......我很确定这个人试图欺骗你.告诉他离开你的网站.

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

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

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

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

有关详情,请访问: https ://developers.google.com/recaptcha/docs/verify

  • 如果您正在向".../siteverify"发出GET请求,那么您将**私钥**放在查询字符串中?那时如何将其视为私钥? (7认同)
  • @TheRueger对[https://www.google.com/recaptcha/api/siteverify](https://www.google.com/recaptcha/api/siteverify)的请求不应该是GET请求,而是POST请求.请参阅[https://developers.google.com/recaptcha/docs/verify](https://developers.google.com/recaptcha/docs/verify). (7认同)
  • TheRueger,非常感谢您的投入!在发表这篇文章之前,我阅读了您在这里提到的所有内容。Google reCAPTCHA 表明服务器端验证是验证方法之一。我对吗?“你只需询问谷歌 g-recaptcha-response 是否有效”是什么意思。我对“验证由谷歌小部件自动完成”和“您将获得带有成功字段的 JSON 响应”这两个步骤感到困惑。如果第一步成功了,为什么还要进行第二步呢?问候 (2认同)
  • @yuck 在这里阅读:http://stackoverflow.com/questions/323200/is-an-https-query-string-secure (2认同)

小智 10

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

检查成功字段是true还是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;
}
Run Code Online (Sandbox Code Playgroud)