壹 ❀ 引
在日常頁面交互中,驗證碼使用是極為頻繁的,登錄注冊驗證,非機器人操作驗證等等,它遍布於每一個網站。說到驗證碼實現,Goole Recaptcha是一個非常不錯的選擇,那么希望通過本文的使用介紹,能讓你對於驗證碼的實現多一種可能性,讓我們開始。
貳 ❀ 使用准備與一些基本概念
貳 ❀ 壹 必要准備
- 需要准備一個谷歌賬號,在創建秘鑰時需要將當前秘鑰與一個谷歌賬號綁定。
- 有特殊上網的途徑,創建秘鑰的地址必須特殊上網,否則無法訪問。
- 具備本地服務器,測試時需要使用,畢竟總不能直接拿項目直接上手,如果你不知道怎么搭建服務器,這里推薦live server,npm下載啟動就可以了,使用非常簡單,這里就不細說了。
貳 ❀ 貳 一些基本概念
Google Rechaptcha版本說明:
reCAPTCHA v3:v3版本可以不通過任何用戶交互進行驗證,並返回一個分數,開發者可以根據分數進行驗證提示,一般用於限制爬蟲等。
reCAPTCHA v2 復選框版本:用戶可以通過點擊“我不是機器人”的復選框,從而觸發圖片選擇以及后續的驗證操作,類似圖。

reCAPTCHA v2 隱式驗證版本:與復選框模式職責相同,區別在於用戶使用時看不到復選框,取而代之的是通過點擊按鈕觸發后續驗證,比如博客園登錄,用戶在輸入完賬號密碼后點擊登錄按鈕,這時會彈出圖片驗證,如果通過了驗證才會發起來登錄請求。
reCAPTCHA v2 Android版本:安卓使用的驗證。
V2版本分為復選框、隱式驗證、安卓三個版本,本文主要圍繞前兩個版本展開介紹,注意,使用不同版本都得創建對應的秘鑰,在開發中如果存在版本替換,一定記得對應替換秘鑰。
Google Rechaptcha秘鑰說明:
秘鑰分為客戶端秘鑰與服務端秘鑰,也就是俗稱的公鑰與私鑰,這是一對,如下圖是我創建的一對秘鑰:

知道了這些,我們現在來創建屬於自己的秘鑰。
貳 ❀ 叄 創建秘鑰
點擊創建秘鑰,雖然此鏈接需要科學訪問,但是界面卻是中文....非常友好,說說創建步驟:
- 輸入標簽,也就是取個名字,萬一版本創建多了好通過標簽區分,這里我就叫
demo
。 - 選擇recaptcha版本,這里我先選擇
進行人機身份驗證復選框
版本。 - 輸入域名,這對秘鑰用在哪,本地服務器啟動一般都是localhost,這里輸入
localhost
。 - 所有者,當前秘鑰創建與哪個郵箱關聯,一般登錄谷歌默認關聯自己的谷歌賬號。
- 接受recaptcha服務條款,向所有者發出提醒,默認勾選不用管。
- 點擊提交,就可以成功創建出一對秘鑰了。
秘鑰有了,現在我們來使用它,開始客戶端(前端)集成。
叄 ❀ 客戶端(前端)集成說明
叄 ❀ 壹 復選框模式的兩種加載方法
v2復選框版本初始化分為自動加載與顯示加載兩種形式,說到底就是提供了兩種初始化模式。自動加載就是將初始化配置直接加在dom上,顯示加載則是利用谷歌提供的API啟動,沒太大區別,我們先說自動加載怎么玩。
不管是自動加載還是顯示加載,第一步都是得引用google recaptcha js資源文件,如下:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
上述引用中的async
與defer
為可選項,用於作用文件下載方式,具體差異請異步JS script腳本async和defer的區別
注意,如果我們項目是國內訪問,需要將www.google.com
替換成www.recaptcha.net
即可。
<script src="https://www.recaptcha.net/recaptcha/api.js" async defer></script>
第二步就是配置dom,最簡單的配置如下:
<div class="g-recaptcha" data-sitekey="客戶端秘鑰"></div>
注意,這個dom標簽必須添加g-recaptcha
的class名,data-sitekey
填寫你創建的秘鑰,刷新頁面,就可以看到驗證碼已經創建好了:

是不是很簡單?當然有的人不喜歡把一堆屬性加在dom上,更希望通過js API來使用,沒關系,我們來看看顯示加載是怎么玩的。
第一步還是引入js資源文件,與上面一樣,這個時候我們創建一個驗證碼容器,其實就是一個裝載驗證碼組件的盒子,如下:
<div id="robot"></div>
標簽沒硬性要求,但一定要加一個id,在js中我們會使用到這個id,接下來是在js中做初始化工作:
grecaptcha.render('robot', {
'sitekey': '6Lfjdd8UAAAAAKzWxI0k59BW5Tcf1C76XPKir1sr', //公鑰
'theme': 'light', //主題顏色,有light與dark兩個值可選
'size': 'compact',//尺寸規則,有normal與compact兩個值可選
'callback': callback, //驗證成功回調
'expired-callback': expiredCallback, //驗證過期回調
'error-callback': errorCallback //驗證錯誤回調
});
刷新頁面,你會發現驗證碼成功展示出來了。聰明的同學已經發現了,grecaptcha.render()
就是驗證碼組件初始化方法,它接受兩個參數,前者為組件容器id,也就是我們在div上添加的robot
;第二個參數是一個對象,也就是組件相關配置。
有同學就納悶了,為啥通過API調用顯示加載可以加這么多屬性,dom形式自動加載能不能加這些配置?當然能,以sitekey
為例,在作為標簽屬性時你得寫作data-sitekey
,同理,theme
用在標簽上時也得加上data-
前綴,其它屬性配置全部如此。
在解釋這些屬性前,我先附上一個完整的例子,大家直接復制替換下公鑰,這樣下面的解釋可以同步修改理解:
<-- HTML部分 -->
<div id="robot"></div>
<button onclick="getResponseFromRecaptcha()">驗證是否通過</button>
<-- 記得引用js -->
<script src="https://www.recaptcha.net/recaptcha/api.js?onload=onloadCallback&render=explicit&hl=en" async defer></script>
//js部分
var callback = function (args) {
console.log(args)
console.log('驗證成功');
};
var expiredCallback = function (args) {
console.log(args)
console.log('驗證過期');
};
var errorCallback = function (args) {
console.log(args)
console.log('驗證失敗');
};
var widgetId;
var onloadCallback = function () {
// 得到組件id
widgetId = grecaptcha.render('robot', {
'sitekey': '6LcYMd4UAAAAABb4jumQHY9ftHhZ3R0N2QxtACCp',
'theme': 'light',
'size': 'compact',
'callback': callback,
'expired-callback': expiredCallback,
'error-callback': errorCallback
});
};
function getResponseFromRecaptcha() {
var responseToken = grecaptcha.getResponse(widgetId);
if (responseToken.length == 0) {
alert("驗證失敗");
} else {
alert("驗證通過");
}
};
叄 ❀ 貳 配置參數說明
sitekey(data-sitekey):客戶端秘鑰,也就是我們創建的秘鑰,這是必填項。
theme(data-theme):驗證碼組件主題色,默認light,還有一個dark可選,顏色對比如下:

size(data-size):驗證碼尺寸規則,默認normal也就是長方形,可選值compact正方形,如下:

callback(data-callback):驗證成功回調,比如用戶點擊了我不是機器人復選框,彈出了圖片,用戶在選擇完圖片點擊右下角的驗證,如果驗證成功便會觸發此回調,比如上方例子驗證成功后輸出了驗證成功
以及一大段亂碼字符,這段字符官方稱為 response token
,后端會使用到這個token,我們在后面具體說。

expired-callback(data-expired-callback):過期回調,如果用戶第一次驗證成功后頁面放置一段時間,當前驗證就會過期,一旦過期谷歌會自動調用過期回調,如下:

error-callback(data-error-callback):錯誤回調,驗證過程中如果出現錯誤便會執行這個回調。
叄 ❀ 叄 API說明
我們已經通過上面的例子了解了初始化組件的API,谷歌驗證碼一共也就提供了三個API,如下:
grecaptcha.render(container,parameters)
初始化API,上文已經解釋了兩個參數的含義,在調用此方法后會返回一個驗證碼組件id,畢竟一個頁面可能會有多處使用驗證碼,該id用於區分不同驗證碼組件。
grecaptcha.reset(opt_widget_id)
重新加載組件API,接受一個參數,也就是render方法返回的驗證碼組件id,如果不填,則默認初始化頁面中第一個驗證碼。
grecaptcha.getResponse(opt_widget_id)
獲取組件驗證狀態的api,同樣接受一個驗證碼id作為參數,用於獲取指定id的驗證碼驗證狀態,如果不填,則默認獲取第一個驗證碼狀態。獲取的結果有兩種情況,如果成功,拿到的也就是前面我們說到的response token,如果失敗則拿到的是空字符串。
在上文例子我們同樣提供了這個方法,大家可以在驗證成功和過期兩種情況下分別點擊驗證是否通過
的按鈕查看不同結果。
有同學一定會納悶getResponse
方法有啥用,說個很簡單的例子,用戶登錄輸完了賬號密碼,只要點擊提交按鈕,我們就可以通過此方法判斷用戶有沒有提前通過驗證,如果通過了再請求登錄接口。
叄 ❀ 肆 url參數說明
細心的同學一定發現上方例子提供的js 引用后綴有點不同,其實js引用地址也接受三個參數,也不是很復雜,我們來解釋下分別表示啥意思:
<script src="https://www.recaptcha.net/recaptcha/api.js onload=onloadCallback&render=explicit&hl=en" async defer
首先,onload,render與hl都不是必填參數,填不填看你自己。
onload:加載所有依賴項后要執行的回調函數的名稱,參考上方例子,等資源加載完畢,我們才執行onloadCallback
方法初始化組件。
render:是否顯式加載組件,默認值為onload
,表示自動加載,也就是默認找到第一個class為g-recaptcha
的標簽來加載組件。例子中我們設置的值為explicit
,意思是不啟用自動加載,而是根據我們提供的DOM id進行加載。
hl:語言種類,你希望組件用哪種語言展示,詳細的語言表參考。如果不設置,則自動檢測瀏覽器語言並作為標准。
OK,到這里,關於復選框模式的使用就全部說完了!!!!!
我們來說說V2隱式驗證版本咋玩,由於是不同版本,這里你得重新創建隱式驗證版本的秘鑰,由於隱式驗證版本只是不展示復選框,改為使用按鈕點擊來觸發圖片選擇驗證,其它API,url屬性等等都是一樣的,這里我就直接給出一個完整的例子:
<-- html部分 -->
<button class="g-recaptcha" data-sitekey="客戶端公鑰" data-callback='onSubmit'>Submit</button>
<script src="https://www.recaptcha.net/recaptcha/api.js" async defer></script>
//js部分
function onSubmit(responToken) {
console.log(responToken);
alert('開始提交表單');
};
兩種復選框模式與隱式驗證模式請根據實際業務場景選擇使用,不存在誰好誰壞。
肆 ❀ 服務端(后端)集成說明
說完客戶端集成,我們來說下服務端如何集成,由於我沒學過后端語言,這里就給不出例子了,具體說下怎么用。這里先解釋下前后端怎么配合。

如上圖,我們來模擬一次完整的驗證過程:
- 用戶點擊登錄按鈕(假設用的是隱式驗證模式),彈出了圖片選擇框,用戶選擇完正確圖片,點擊了驗證按鈕。
- 這時其實會對谷歌發起請求,請求成功,前端拿到了
response token
。 - 前端請求與后端協商好的接口A,把
response token
帶給后端。 - 后端拿着私鑰與
response token
請求谷歌提供的接口地址B,成功並拿到了驗證結果。 - 后端將這份數據再返回給前端,前端判斷成功,這時才開始請求登錄接口。
那么后端需要請求的接口地址B就是https://www.google.com/recaptcha/api/siteverify
,請求方式為POST
。
POST
參數有三個,我們來說下分別是什么:
secret(必填):私鑰,也就是我們創建秘鑰時,給服務端用的那個秘鑰。
response(必填):response token
,這個由用戶在前端操作后產生,有效期為2分鍾,且只能用一次。
remoteip(選填):用戶ip。
返回數據格式如下:
{
"success": true|false,
"challenge_ts": timestamp, // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
"hostname": string, // the hostname of the site where the reCAPTCHA was solved
"error-codes": [...] // optional
}
錯誤碼分類這里我就不列了,具體可以查看錯誤碼說明。
有的同學一定會疑惑,用戶操作完成前端不是已經知道驗證成功失敗了嗎,何必多次一舉還麻煩后端去請求呢。常理上來說,只通過前端驗證也是可以的,只是后端無法感知。比如博主公司已經有了一套驗證碼系統,國內用這套,國外用谷歌這套,為了統一驗證碼驗證規則,還是統一由后端提供驗證碼接口讓前端調用,這個就看各位實際業務場景是什么樣了。
好了,關於google recaptcha介紹到這里就結束了,如果有問題或疑問歡迎留言,我會在第一時間回復你。
那么到這里,本文正式結束。