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

2022-09-01 02:14:35

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

我正在玩一个谷歌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>

我能够看到显示的验证码图像,如下所示:

enter image description here

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

enter image description here

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

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

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

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

我错过了什么吗?


答案 1

关于新的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

编辑:它实际上是一个POST,根据这里的文档


答案 2

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

检查成功字段中的真或假

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