在Laravel/Lumen中快速整合Invisible reCPATCHA

前言

在上一篇的文章中,我們提到了今年Google宣佈推出最新版的機器人識別技術-Invisible reCPATCHA,而在這片文章中將教你如何快速的在你的Laravel專案中應用這項技術。

前端驗證指南

根據Google官方的文件指南看來,其實Invisible reCPATCHA的背後驗證的技術與前一代的no captcha應該不會相差太多,使用與前一代的API相同的引入位置: https://www.google.com/recaptcha/api.js,但既然Invisible reCPATCHA是完全隱形的,那該如何觸發進行驗證動作的時機呢?

其實很簡單,API只需要和你的submit button的送出事件綁定在一起,API即可在你正式送出表單資料前與Google的驗證伺服器完成驗證,以下為Google官方文件所提供的前端範例:

<html>
  <head>
    <title>reCAPTCHA demo: Simple page</title>
     <script src="https://www.google.com/recaptcha/api.js" async defer></script>
     <script>
       function onSubmit(token) {
         document.getElementById("demo-form").submit();
       }
     </script>
  </head>
  <body>
    <form id='demo-form' action="?" method="POST">
      <button class="g-recaptcha" data-sitekey="your_site_key" data-callback='onSubmit'>Submit</button>
      <br/>
    </form>
  </body>
</html>

在綁定的button元素中需註記於Google申請的site key並設定驗證完成後的callback事件,若是驗證通過,Google會回傳一個名稱為g-recaptcha-response的欄位並連同你整份表單一起送往Server端進行驗證。

後端驗證指南

如果前端驗證流程正確,應該表單送來時會帶上一個名稱為g-recaptcha-response的參數,我們需要利用他向Google詢問該token是否為合法的驗證結果。

Token驗證位置: https://www.google.com/recaptcha/api/siteverify

傳送參數:

  • secret (Required. The shared key between your site and reCAPTCHA.)
  • response (Required. The user response token provided by reCAPTCHA, verifying the user on your site.)
  • remoteip (Optional. The user's IP address.)

呼叫Method: POST

成功呼叫後,Google會回傳一個Json的Response如下:

{
  "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
}

在Laravel/Lumen中快速整合Invisible reCPATCHA

前面說明了那麼多流程其實不難,但是當自己要實作時總是要花上不少時間,所以我就寫了一個package供Laravel/Lumen或是原生PHP專案中能快速整合Invisible reCPATCHA

申請Key

在開始串接前,請先至 http://www.google.com/recaptcha/admin 申請串接recaptcha的key,注意在申請時記得勾選invisible reCAPTCHA的選項

安裝package

該package已經上傳至packagist,所以只需要透過composer就能夠快速安裝

composer require albertcht/invisible-recaptcha

在Laravel中設定package

app/config/app.php中加入package的service provider

AlbertCht\InvisibleReCaptcha\InvisibleReCaptchaServiceProvider::class,

接著在.env設定檔中加入以下的設定:

INVISIBLE_RECAPTCHA_SITEKEY={siteKey}
INVISIBLE_RECAPTCHA_SECRETKEY={secretKey}
INVISIBLE_RECAPTCHA_BADGEHIDE=false

雖然說Invisible reCPATCHA號稱使用上是隱形的,但卻不全然是這樣 他會預設在你使用驗證API的網頁右下方多一個badge logo來表示你的網站使用Invisible reCPATCHA的技術。

如果你不希望在你的網頁中顯示那個badge logo的話,你可以將INVISIBLE_RECAPTCHA_BADGEHIDE設定成true即可隱藏(官方不建議)。

前端整合

接下來你只需要在希望驗證的form中加入以下的render程式碼

{!! app('captcha')->render(); !!}

後端整合

在後端要驗證是否通過也非常簡單,只需要在validation中加入'g-recaptcha-response' => 'required|captcha'即可。

$validate = Validator::make(Input::all(), [
	'g-recaptcha-response' => 'required|captcha'
]);

客製化submit function

如果說你希望在按下sumit button表單送出前trigger某些客製化的行為,你只需要在javascript中實作_submitEvent這個function

_submitEvent = function() {
    console.log('submit button clicked.');
    // write your logic here
    // submit the form in the end
    _captchaForm.submit();
}

使用注意事項

  • 前端的render function一定要在form元素底下呼叫
  • 在該form元素只能存在一個typesubmit的按鈕

Github地址

https://github.com/albertcht/invisible-recaptcha
歡迎回報bug或是PR喔!