Jetpack 表單加入 Google reCAPTCHA v3 AJAX 保護免外掛,非 WordPress 也適用
![Jetpack 表單加入 Google reCAPTCHA v3 AJAX 保護免外掛,非 WordPress 也適用](https://i0.wp.com/footmark.com.tw/wp-content/uploads/2022/01/3748f21251dedb12e258d3fac8d39cf0.jpg?fit=450%2C236&ssl=1)
使用 WordPack 免外掛方式,在 Jetpack 表單加入 Google reCAPTCHA v3 保護機制,以分數驗證我不是機器人並搭配 AJAX 即時判斷,也適一般非 WordPress 網站。
Google reCAPTCHA v3
註冊
進入 Google reCAPTCHA 管理頁面,並以下圖新增 reCAPTCHA v3。
![](https://i0.wp.com/footmark.com.tw/wp-content/uploads/2022/01/c3c2b6aa2999774b09f29fd542b9dda3.png?resize=1024%2C601&ssl=1)
Google 提供 reCAPTCHA 類型兩種方式:
- eCAPTCHA v3:以分數驗證要求,完全不須用戶做什麼就能自動判斷您是人類 or 機器人 (也是我們要用的類型)。
- eCAPTCHA v2:以問題驗證要求。
接著可設定此次 reCAPTCHA 能夠使用的整個網域 or 單個子網域。
![](https://i0.wp.com/footmark.com.tw/wp-content/uploads/2022/01/491b092d9ba9ce2d2b3858d410235573.png?resize=1024%2C601&ssl=1)
![](https://i0.wp.com/footmark.com.tw/wp-content/uploads/2022/01/5956cfa88b1f60dd3e1a75b890dbd0a6.png?resize=1024%2C601&ssl=1)
查看前端金鑰;後端密鑰
點擊【設定】。
![](https://i0.wp.com/footmark.com.tw/wp-content/uploads/2022/01/fe36ec2fb9dde52e0ece9ab414881ffa.png?resize=1024%2C601&ssl=1)
就能看到剛新增 reCAPTCHA v3 的前端金鑰;後端密鑰。
![](https://i0.wp.com/footmark.com.tw/wp-content/uploads/2022/01/7419cc1cca9c0557d1939b5082fe80bd.png?resize=1024%2C630&ssl=1)
WordPress
/wp-content/themes/[theneName]/.footer.php 載入 Google reCAPTCHA 的 JavaScript:
《參考:reCAPTCHA v3 | Google Developers》
<!-- 以上省略 -->
<!-- 引用 JS -->
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<?php wp_footer(); ?>
</body>
</html>
Jetpack
後台新增 Jetpack 表單頁面。
![](https://i0.wp.com/footmark.com.tw/wp-content/uploads/2022/01/55e30ffbbc5a2d3af82514c19c6c6905.png?resize=1024%2C567&ssl=1)
![](https://i0.wp.com/footmark.com.tw/wp-content/uploads/2022/01/caa1c882492e92e25768256daeff9f4e.png?resize=1024%2C567&ssl=1)
查看表單送出按鈕以此 class 名稱,讓後續 JavaScript 能夠取得該按鈕。
![](https://i0.wp.com/footmark.com.tw/wp-content/uploads/2022/01/ebaa294459d8af99c6e3d730c788864a.png?resize=1024%2C567&ssl=1)
程式
《參考:reCAPTCHA v3 | Google Developers》
前端 JavaScript
以該 WordPress 網站僅「需求洽詢」須使用 Google reCAPTCHA v3,先將 reCAPTCHA v3 規定的值加入至 Jetpack 送出表單按鈕,並以 AJAX 方式先向後端 PHP 取得 reCAPTCHA v3 驗證分數來判斷是人類 or 機器人:
- 人類:送出表單。
- 機器人:無法送出表單,須重新整理頁面,再送出表單。
// 僅「需求洽詢」頁面
if (/page-id-8623/.test(document.body.className)) {
// 取得 Jetpack 送出表單 <button>
var button = document.querySelector('.wp-block-button__link');
/**
* reCAPTCHA v3 | Google Developers https://developers.google.com/recaptcha/docs/v3#automatically_bind_the_challenge_to_a_button
*/
// 將 reCAPTCHA v3 規定的值加入至 Jetpack 送出表單 <button>
button.className = button.className + ' g-recaptcha';
button.dataset.sitekey = '前端金鑰';
button.dataset.action = 'contact';
button.dataset.callback = 'verifyCallback';
// 先停止 Jetpack 送出表單 <button> click 功能,等待 reCAPTCHA v3 回傳認證後確定非 bot 在送出
button.addEventListener('click', (event) => {
event.preventDefault();
})
function verifyCallback(token) {
let form = document.querySelector('.contact-form'); // 取得表單
let formData = new FormData();
// 要 POST 到 Server 的值
formData.append('token', token);
formData.append('action', button.dataset.action);
// Server 檔案路徑
fetch('/recaptcha-v3.php', {
method: "POST",
body: formData
})
.then(response => response.json())
.then(result => {
if(result.success) {
// 分數須大於 0.5,才當作是人類操作 (可依需求自行調整)
if(result.score >= 0.9) {
console.log('判斷為真人,送出表單');
// 判斷是真人時,送出 Jetpack 表單
form.submit();
// 分數低於 0.8,當作機器人
} else {
alert('您被判定為機器人,請重新整理網頁,再試一次。');
}
} else {
window.alert(result['error-codes'][0])
}
})
.catch(err => {
window.alert(err)
})
}
}
後端 PHP
PHP 接收【前端金鑰】並與【後端密鑰】比對是否匹配才執行驗證,將此 PHP 程式檔放置於網站根目錄下 / (這與前端 JavaScript 所發送給後端路徑有關,如欲更動,前後端須匹配):
<?php
define("RECAPTCHA_V3_SECRET_KEY", '後端密鑰');
$token = $_POST['token'];
$action = $_POST['action'];
// call curl to POST request
$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(array('secret' => RECAPTCHA_V3_SECRET_KEY, 'response' => $token)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$arrResponse = json_decode($response, true);
// 直接回傳,讓前端判斷
echo $response;
// or 先判斷在回傳前端
// verify the response
if($arrResponse["success"] == '1' && $arrResponse["action"] == $action && $arrResponse["score"] >= 0.5) {
// valid submission
// go ahead and do necessary stuff
} else {
// spam submission
// show error message
}
CSS 調整 reCAPTCHA v3 位置
許多網頁右下方很常放一些如回到最頂部按鈕,Google reCAPTCHA v3 圖標也在右下方,所以時常會發生重疊,因此我們可以設定 CSS 讓 Google reCAPTCHA v3 圖標變換至左下方的 CSS 如下:
《參考:How To Move The reCAPTCHA v3 badge to the left side - DiviMundo》
/* Move reCAPTCHA v3 badge to the left */
.grecaptcha-badge {
width: 70px !important;
overflow: hidden !important;
transition: all 0.3s ease !important;
left: 0px !important;
}
.grecaptcha-badge:hover {
width: 256px !important;
}
完成結果
出現 Google reCAPTCHA v3 圖標,表示此表單正受保護,即可防止機器人填表單的問題。
![](https://i0.wp.com/footmark.com.tw/wp-content/uploads/2022/01/9c15d4c9cf710a0d46a2bd7ae4c49ad9.png?resize=1024%2C630&ssl=1)
![創用 CC 授權條款](https://i.creativecommons.org/l/by-sa/3.0/tw/88x31.png)
本著作係採用創用 CC 姓名標示-相同方式分享 3.0 台灣 授權條款授權.