為了防止機器人說惡意攻擊,我們引入了 captcha,就是那個亂七八糟的字要人類去辨識內容的輸入框,但那種東西其實是廢物,因為目前的辨識軟體早就能輕鬆的破解內容了(請看結論)。
此外還會造成使用者的厭煩,在資安上大概只是為了心裡上的安慰而已,安慰資料檢查業務的人,沒有實際的意義。
anyway,我們引入google 的recaptcha來解決這個問題,recaptcha有v2和v3兩個版本,v3的話不必按那個我是人類的核取框,也不必點擊那些看不懂的圖片(例如問你那些圖片有單車)。
所以我採用v3的版本。
使用 recaptcha v3
申請和設定
進到 google rechptcha的頁面
https://www.google.com/recaptcha/about/
進到console admin中新增一個服務
https://www.google.com/recaptcha/admin/
相關設定可以參考[2]的說明文件,這裡略。
申請完畢會拿到一個sitekey和secret,sitekey是前端用的,secret是後端用的。
一次可以同時設定多個網域。
放到網頁上
官網[3]的說明這部分很簡單,原理是在送出submit之後,先進行recaptcha的驗證,通過再把表單送到後端,只要三步驟就完成。
<script src="https://www.google.com/recaptcha/api.js"></script>
<script src="https://www.google.com/recaptcha/api.js"></script>
1. 加入js
2. 寫入一個函數,替你的 form 作送出的動作,記得替你的form加上id
function onSubmit(token) {
document.getElementById("demo-form").submit();
}
</script>
3. 把你的 submit 按鈕改成
<button class="g-recaptcha"
data-sitekey="<<改成你的reCAPTCHA_site_key>>"
data-callback='onSubmit'
data-action='submit'>Submit
</button>
這樣你的按鈕右下就會出現recaptcha的符號,大功告成!
咦?!這樣就好了?
其實我在這地方想了很久,第2個步驟並沒有任何的防止動作啊?
伺服器端檢查
後來參考[2]的說明給了靈感自己完成伺服端的驗證。
伺服器取得由前端送來的tocken,進行檢查。
我的作法是透過 ajax的方式送到後端檢查,取得recaptcha的分數。
他的分數是 0~1。0是機器人,1是人類。
以下程式取得此分數
PHP 範例
public function getReCaptcha($token=""){ if(!$token)return 0; $client = \Config\Services::curlrequest(); //引用curl函數 $uri = 'https://www.google.com/recaptcha/api/siteverify'; $response = $client->request('POST', $uri, [ 'form_params' => [ "secret"=> <recaptchaSecret 放這>, "response" => $token, "remoteip" => $_SERVER["REMOTE_ADDR"] ], ]); $body = $response->getBody(); if($body){ $para = json_decode($body,true); return $para['score']; } // 預設給分=0.5通過,問不到的情況 return 0.5; }
第3行 引用curl的函數,因為我是用ci4,所以可以直接這樣引用。
第12行 取得的$body物件,內容欄位大概如下:
後端程式由取回的分數判斷是否要回應正確的資料。這部分就請自行依需要設計。
結論
使用 recaptcha v3是明智的選擇,不必有繁瑣或多餘的操作。
記得有看過一個影片,验证码大战AI:神仙打架,我们遭殃,验证码还能变简单吗? Verification code vs. AI: Can verification code become simpler?指出(3:56秒處),
像下圖的驗證碼,ai的辨識度達到99.8%的準確率,而人類只有33.3%。換句話說,答錯的才是人類。
也許有人說你可以改驗證方式,但最後還是會輸給ai,所以最後驗證碼是要阻止人類使用服務。
總之結合recaptcha v3前後端驗證,可以防止機器人的攻擊。
參考資料
[1] https://www.google.com/recaptcha/about/
[2] https://www.letswrite.tw/recaptcha-v3/
[3] https://developers.google.com/recaptcha/docs/v3