簡體   English   中英

Google reCAPTCHA:如何在服務器端獲取用戶響應並進行驗證?

[英]Google reCAPTCHA: How to get user response and validate in the server side?

我正在做一個 Java (JSP + Servlet) web 應用程序(我知道這個問題與技術無關)。 我希望使用最新的谷歌 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 提供的選項?

我想念什么嗎?

新的 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。

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

嗨好奇你可以在客戶端驗證你的谷歌 recaptcha 也100%為我工作來驗證你的谷歌 recaptcha 只是看下面的代碼
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" />

此代碼放在調用get_action(this)方法表單按鈕的 head 部分:

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

這是完整的演示代碼,用於了解客戶端和服務器端流程。 您可以復制粘貼它,只需替換谷歌站點密鑰谷歌密鑰。

<?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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM