Google reCAPTCHA:如何在服务器端获取用户响应并进行验证?

新手上路,请多包涵

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

我正在玩这里的 Google 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>

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

在此处输入图像描述

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

在此处输入图像描述

如您所见,有一个验证按钮,根据我的测试,用户响应会发送给 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 提供的选项?

我想念什么吗?

原文由 curious1 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 938
2 个回答

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

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

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

用人类的语言来说,就像,

  • _你的服务器_:嘿谷歌,有一个家伙告诉我他不是机器人。他说你已经确认他是人了,他让我把这个令牌给你作为证明。
  • _谷歌_:嗯……让我检查一下这个令牌……是的,我记得我 给了他 这个令牌……是的,他是血肉之躯让他通过了。
  • _你的服务器_:嘿谷歌,还有另一个人告诉我他是一个人。他还给了我一个令牌。
  • _谷歌_:嗯……这和你上次给我的令牌是一样的……我很确定这家伙想愚弄你。告诉他离开你的网站。

验证响应非常容易。只需向

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

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

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

此处提供更多信息: https ://developers.google.com/recaptcha/docs/verify

编辑:根据 此处的文档,它实际上是一个 POST。

原文由 TheRueger 发布,翻译遵循 CC BY-SA 4.0 许可协议

我在登录 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;
}

原文由 Rob Kraft 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题