Google 我不是機器人 reCAPTCHA Ajax 驗證碼教學範例 for PHP

使用 Google 提供的「我不是機器人」reCAPTCHA 點擊驗證方式,並個別以傳統表單、Ajax JavaScript、Ajax jQuery 實作的教學範例。

google-recaptcha-ajax-for-php_00

Google 提供的「我不是機器人」點擊驗證方式,不僅可有效防止自動提交機器人 robot 與暴力破解取得帳號、密碼,也成功取代舊有的「圖形」輸入驗證碼方式,大大提升了使用者體驗。

註冊

使用前必須先到 reCAPTCHA 申請 > 點擊右上角的「Get reCAPTCHA」> 資料填寫完後點擊「Register」。

  • Label:輸入網站的名稱(自訂)
  • Domains:輸入網域名稱(使用換行可設定多個)
  • Send alerts to owners:當有問題時會主動通知您
google-recaptcha-ajax-for-php_01

使用說明

Keys

  • Site Key(公鑰):用在「客戶端」HTML,提供 reCAPTCHA 驗證碼服務給使用者
  • Secret key(密鑰):用在「伺服器端」,網站與 Google 之間的通訊

client-side integration

「客戶端」的使用說明。

  • <script>:Google reCAPTCHA 的 API js 檔
  • <div>:reCAPTCHA 小工具出現的位置

Server side integration

「伺服器端」的使用說明。

google-recaptcha-ajax-for-php_02

細節說明與配置

點擊 The reCAPTCHA documentation site 進入更多細節說明與配置。

這邊可看到有二種版本

  • Version 1.0 舊版:「圖形」輸入驗證碼方式
  • Version 2.0 新版:「我不是機器人」點擊驗證方式

點擊「Introduction」> 下載 Google 已建立好的 reCAPTCHA PHP 類別範例,點擊 PHP

google-recaptcha-ajax-for-php_03

點擊「Clone or download」>「Download ZIP」下載檔案。

google-recaptcha-ajax-for-php_04

範例

建立目錄 includes,並將下載的 recaptcha-master.zip > src 目錄下的檔案解壓縮至 includes,在選擇以下其中一種方式,新增的檔案與 includes 放置在同目錄下。

傳統表單

開啟 線上範例

傳送 – index.php

<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
    <meta charset="UTF-8">
    <title>傳統表單 | reCAPTCHA 範例 - 傳送</title>

    <!-- Google reCAPTCHA icon -->
    <link rel="shortcut icon" href="//www.gstatic.com/recaptcha/admin/favicon.ico" type="image/x-icon"/>
</head>
<body>
    
    <h1>reCAPTCHA 範例 - 傳送</h1>

    <?php
    // 註冊或查詢你的 API Keys: https://www.google.com/recaptcha/admin
    $siteKey = '你的 Site key';

    // 所有支援的語系: https://developers.google.com/recaptcha/docs/language
    $lang = 'zh-TW';

    // 如果未填入 API Key
    if ($siteKey === '') {
        echo '
    <h2>新增 API key</h2>
    <p>如果沒有的話可以去這申請 <a href="https://www.google.com/recaptcha/admin">Google reCAPTCHA</a>。</p>';
    } else {
        echo '
    <p>點擊「我不是機器人」後,送出表單‧</p>

    <form action="captcha.php" method="post">
        <fieldset>
            <legend>一個範例</legend>

            <label>
                範例 input A: <input type="text" name="ex-a" value="foo">
            </label>
            <br /><br />

            <label>
                範例 input B: <input type="text" name="ex-b" value="bar">
            </label>
            <br /><br />

            <div class="g-recaptcha" data-sitekey="' . $siteKey . '"></div>
            <script type="text/javascript" src="https://www.google.com/recaptcha/api.js?hl=' . $lang . '"></script>
            <br />

            <input type="submit" value="送出" />
        </fieldset>
    </form>';
    }
    ?>

</body>
</html>

接收 – captcha.php

<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
    <meta charset="UTF-8">
    <title>傳統表單 | reCAPTCHA 範例 - 接收</title>

    <!-- Google reCAPTCHA icon -->
    <link rel="shortcut icon" href="//www.gstatic.com/recaptcha/admin/favicon.ico" type="image/x-icon"/>
</head>
<body>
    
    <h1>reCAPTCHA 範例 - 接收</h1>

    <?php
    require_once __DIR__ . '/includes/recaptcha/autoload.php';

    // 註冊或查詢你的 API Keys: https://www.google.com/recaptcha/admin
    $secret = '你的 Secret key';

    if (isset($_POST['g-recaptcha-response'])) {
        $recaptcha = new \ReCaptcha\ReCaptcha($secret);
        // 確認驗證碼與 IP
        $resp = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);

        $var = var_export($_POST, true);

        echo '
    <h2>POST data</h2>
    <pre>' . $var . '</pre>';

        // 確認正確
        if ($resp->isSuccess()) {
            echo '
    <h2>Success!</h2>
    <p>確認正確</p>
    <a href="index.php">在試一次</a>';
        }
        // 確認失敗
        else {
            echo '
    <h2>確認失敗</h2>
    <p>返回以下錯誤。</p>';

            foreach ($resp->getErrorCodes() as $code) {
                echo '<p>' . $code . '</p> ';
            }

            echo '
    <p>檢查引用的錯誤代碼 <a href="https://developers.google.com/recaptcha/docs/verify#error-code-reference">https://developers.google.com/recaptcha/docs/verify#error-code-reference</a>。</p>
    <p><strong>Note:</strong> 程式錯誤,使用者沒有完成 reCAPTCHA 驗證碼。</p>
    <a href="index.php">在試一次</a>';
        }
    }
    ?>

</body>
</html>

Ajax JavaScript

開啟 線上範例

傳送 – index.php

<?php
// 註冊或查詢你的 API Keys: https://www.google.com/recaptcha/admin
$siteKey = '你的 Site key';

// 所有支援的語系: https://developers.google.com/recaptcha/docs/language
$lang = 'zh-TW';
?>

<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
    <meta charset="UTF-8">
    <title>Ajax JavaScript | reCAPTCHA 範例</title>
    
    <script type="text/javascript" src="https://www.google.com/recaptcha/api.js?hl=<?php echo $lang; ?>&onload=onloadCallback&render=explicit" async defer></script>
    <script type="text/javascript">
    var verifyCallback = function(response) {
        // 如果 JavaScript 驗證成功
        if (response) {
            // 發送 Ajax 查詢請求並處理
            var request = new XMLHttpRequest();
            request.open("POST", "captcha.php");

            // POST 參數須使用 send() 發送
            var data = "g-recaptcha-response=" + response;

            // POST 請求必須設置表頭在 open() 下面,send() 上面
            request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            request.send(data);

            request.onreadystatechange = function() {
                // 伺服器請求完成
                if (request.readyState === 4) {
                    // 伺服器回應成功
                    if (request.status === 200) {
                        var type = request.getResponseHeader("Content-Type");   // 取得回應類型

                        // 判斷回應類型,這裡使用 JSON
                        if (type.indexOf("application/json") === 0) {   
                            var data = JSON.parse(request.responseText);
                            var success = document.getElementById('success');

                            // 如果 PHP 驗證成功
                            if (data.success) success.innerHTML = '驗證成功';
                            else success.innerHTML = '驗證失敗';
                        }
                    } else {
                        alert("發生錯誤" + request.status);
                    }
                }
            }
        }
    };

    /*
     * recaptcha API 參考 https://developers.google.com/recaptcha/docs/display
     */
    var onloadCallback = function() {
        grecaptcha.render(
            'my-widget', {                              // widget 驗證碼視窗在 id="my-widget" 顯示
                'sitekey' : '<?php echo $siteKey; ?>',  // API Key
                'callback' : verifyCallback,            // 要呼叫的回調函式
                'theme' : 'dark'                        // 主題
            }
        );
    };
    </script>

    <!-- Google reCAPTCHA icon -->
    <link rel="shortcut icon" href="//www.gstatic.com/recaptcha/admin/favicon.ico" type="image/x-icon"/>
</head>
<body>
    
    <!-- 顯示驗證成功與否 -->
    <h1 id="success"></h1>

    <!-- reCAPTCHA 小工具出現的位置 -->
    <!-- POSTs back to the page's URL upon submit with a g-recaptcha-response POST parameter. -->
    <div id="my-widget"></div>

</body>
</html>

接收 – captcha.php

<?php
header('Content-type: application/json');

require_once __DIR__ . '/includes/recaptcha/autoload.php';

// 註冊或查詢你的 API Keys: https://www.google.com/recaptcha/admin
$secret = '你的 Secret key';

if (isset($_POST['g-recaptcha-response'])) {
    $recaptcha = new \ReCaptcha\ReCaptcha($secret);
    // 確認驗證碼與 IP
    $resp = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);

    $var = var_export($_POST, true);

    // 確認正確
    if ($resp->isSuccess()) echo json_encode(array('success' => true));
}

Ajax jQuery

開啟 線上範例

傳送 – index.php

<?php
// 註冊或查詢你的 API Keys: https://www.google.com/recaptcha/admin
$siteKey = '你的 Site key';

// 所有支援的語系: https://developers.google.com/recaptcha/docs/language
$lang = 'zh-TW';
?>

<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
    <meta charset="UTF-8">
    <title>Ajax jQuery | reCAPTCHA 範例</title>
    
    <!-- Google jQuery -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    
    <script type="text/javascript" src="https://www.google.com/recaptcha/api.js?hl=<?php echo $lang; ?>&onload=onloadCallback&render=explicit" async defer></script>
    <script type="text/javascript">
    /*
     * recaptcha API 參考 https://developers.google.com/recaptcha/docs/display
     */
    var verifyCallback = function(response) {
        // 如果 JavaScript 驗證成功
        if (response) {
            $.post('captcha.php', { 'g-recaptcha-response': response }, function(data, status) {
                // 如果 PHP 驗證成功
                if (status == 'success') $('#success').text('驗證成功');
                else $('#success').text('驗證失敗');
            });
        }
    };

    var onloadCallback = function() {
        grecaptcha.render(
            'my-widget', {                              // widget 驗證碼視窗在 id="my-widget" 顯示
                'sitekey' : '<?php echo $siteKey; ?>',  // API Key
                'callback' : verifyCallback,            // 要呼叫的回調函式
                'theme' : 'dark'                        // 主題
            }
        );
    };
    </script>

    <!-- Google reCAPTCHA icon -->
    <link rel="shortcut icon" href="//www.gstatic.com/recaptcha/admin/favicon.ico" type="image/x-icon"/>
</head>
<body>
    
    <!-- 顯示驗證成功與否 -->
    <h1 id="success"></h1>

    <!-- reCAPTCHA 小工具出現的位置 -->
    <!-- POSTs back to the page's URL upon submit with a g-recaptcha-response POST parameter. -->
    <div id="my-widget"></div>

</body>
</html>

接收 – captcha.php

<?php
header('Content-type: application/json');

require_once __DIR__ . '/includes/recaptcha/autoload.php';

// 註冊或查詢你的 API Keys: https://www.google.com/recaptcha/admin
$secret = '你的 Secret key';

if (isset($_POST['g-recaptcha-response'])) {
    $recaptcha = new \ReCaptcha\ReCaptcha($secret);
    // 確認驗證碼與 IP
    $resp = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);

    $var = var_export($_POST, true);

    // 確認正確
    if ($resp->isSuccess()) echo json_encode(array('success' => true));
}


發表迴響