最近在工作上接觸到了 reCAPTCHA,目的是為了減少大量的廣告留言、貼文,但以往使用 reCAPTCHA 都需要在頁面上擺個「我不是機器人」的 checkbox,對於要在舊系統上加入 checkbox 且不失美觀又是另一個問題了,於是決定採用「v2 Invisible」
但你可能會想,阿不是有新的 v3 完全不用勾選「我不是機器人」也不用認識各國紅綠燈?
對,事實上我們是先採用了 v3,可是誤判成機器人的機率太高,於是嘗試改用 v2 的 Invisible。
reCAPTCHA 是什麼
看了下面的圖想必你對 reCAPTCHA 應該不陌生
通常會在有表單的地方出現,像是註冊帳號、發文、留言等等的區塊或頁面,避免被非實體人類使用者濫用。
然而在實作上又分成了 v2 Checkbox
、v2 Invisible
、v3
三種不同驗證方式可以選擇。
v2 Checkbox
需要在頁面中插入如上圖中「我不是機器人」的 checkbox,在使用者勾選後再由 reCAPTCHA 判斷通過或是需再做視力測驗,選擇紅綠燈、公車、腳踏車、店家大門之類的。
v2 Invisible
需要在頁面中插入一 reCAPTCHA client element,但不會對畫面呈現有任何改變,畢竟人家都叫 Invisible 了,而觸發驗證時機可以綁在表單按鈕上或透過 reCAPTCHA JS API 執行,若被判斷為有疑慮才會跳出拼圖做進一步的驗證。
v3
於 2018 年底推出的新版本,在驗證過程中完全不會經過任何 reCAPTCHA 的 UI,即上方 checkbox 或拼圖,直接判斷使用者行為給予介於 0.0 到 1.0 的分數,讓開發者自行設定分數判別的標準。
註冊 reCAPTCHA v2 Invisible
若要在你的網站中加入 reCAPTCHA 則要先註冊取得 key,由此新增一組 v2 Invisible 的應用
接著可以在設定中找到此組應用的「網站金鑰 (site key)」與「密鑰 (secret key)」,在將 reCAPTCHA client 加入頁面中與驗證時會用到
開始使用 reCAPTCHA v2 Invisible
官方文件: https://developers.google.com/recaptcha/docs/invisible
從官方教學中可以看到主要分成三種使用方式
- Automatically bind the challenge to a button
- Programmatically bind the challenge to a button
- Programmatically invoke the challenge
但今天就直接切入第三種來介紹,需求是單一頁面中有許多輸入框在送出前都需使用 reCAPTCHA 來做驗證。
Include script
<script src="https://www.google.com/recaptcha/api.js"></script>
在有需要用到 reCAPTCHA 的頁面都須先引入此 script 才能作用。
grecaptcha
成功載入 reCAPTCHA script 後即可獲得 grecaptcha
全域變數,並可透過其來初始化 reCAPTCHA client 及觸發驗證 (grecaptcha.execute),詳細用法可參考下圖或官方文件
reCAPTCHA client
其實就是個隨意的 HTML element,用來初始化 reCAPTCHA 的對象,像是隨便一個帶有 id
以及 data-size="invisible"
的 div
,若沒有加上 data-size="invisible"
則會在畫面中顯示 checkbox
<div id="recaptchaClient" data-size="invisible"></div>
而後就可以用 grecaptcha.render
來初始化得到一個 reCAPTCHA client
grecaptcha.render('recaptchaClient', {
// config
});
觸發驗證
當頁面中已有 reCAPTCHA client 時及可透過 grecaptcha.execute()
來進行 reCAPTCHA 的機器人判斷,並在必要時跳出拼圖做進一步的確認,當使用者通過後可從 callback
中獲取一 token
,此外需要注意的是,當每次驗證完成後記得要 reset 才能再對同一個 reCAPTCHA client 觸發驗證
<div id="recaptchaClient" data-size="invisible"></div>
<script>
grecaptcha.render('recaptchaClient', {
sitekey: 'YOUR RECAPTCHA SITE KEY',
callback: token => {
console.log(token);
grecaptcha.reset();
}
});
grecaptcha.execute();
</script>
最後就只差把觸發時機綁在正確的位置,如 onClick,若有必要可使用 grecaptcha.ready
確保 grecaptcha API 已初始完成
模組化
從上面的範例中可以發現一個問題:callback 只能有一個,而且在 grecaptcha.render()
時就定義好了。
如此一來當頁面中有兩個不同的表單都需要先過 reCAPTCHA 再戳各自的 API endpoint 時就有些許麻煩了,於是這邊抽出 src/reCAPTCHA-v2-invisible.js
將 reCAPTCHA 模組化,方便客製化每個 execute
的 callback,在觸發驗證時則變成
reCAPTCHA_v2_invisible.execute(token => {
// do something
});
驗證 token
從 callback 中拿到 token 後,需要透過 google 的 server 來驗證此 token 的正確性,詳細說明可參考官方文件。
在使用上只需將 response: {{token}}
與 secret: {{secret key}}
POST 至 https://www.google.com/recaptcha/api/siteverify 然後拿到 response 就大功告成了。
此篇文章僅是第一次使用 reCAPTCHA 的紀錄,文中若有任何錯誤資訊還請糾正,如果你喜歡這邊文章的話可以拍 10 下手,不喜歡的話可以拍 1 下再分享給 5 個人,感謝你的閱讀。