SafetyNet reCAPTCHA API

SafetyNet 服務包含 reCAPTCHA API,可用來保護應用程式不受惡意流量影響。

reCAPTCHA 是免付費服務,採用進階風險分析引擎,可保護應用程式免受垃圾內容和其他濫用行為的影響。如果服務認為與應用程式互動的使用者可能是機器人,而非真人,就會提供人機驗證 (CAPTCHA),使用者必須通過驗證才能繼續執行應用程式。

本文說明如何將 reCAPTCHA API 從 SafetyNet 整合至應用程式。

附加服務條款

存取或使用 reCAPTCHA API,即表示您同意《Google API 服務條款》和下列 reCAPTCHA 服務條款。請詳閱並瞭解所有適用條款與政策後再存取 API。

reCAPTCHA 服務條款

您知悉並瞭解 reCAPTCHA API 運作時會收集軟硬體資訊 (例如裝置和應用程式資料) 與完整性檢查結果,並將收集到的資料傳送給 Google 進行分析。根據《Google API 服務條款》第 3(d) 節規定,您一旦使用這些 API,即表示您同意負責向使用者提供任何必要通知,說明系統會蒐集上述資料並提供給 Google,以及徵求使用者同意。

註冊 reCAPTCHA 金鑰組

如要註冊與 SafetyNet reCAPTCHA API 搭配使用的金鑰組,請前往 reCAPTCHA Android 註冊網站,然後完成以下步驟:

  1. 在顯示的表單中提供下列資訊:

    • 標籤:金鑰的專屬標籤,通常應使用公司或機構的名稱。
    • reCAPTCHA 類型:依序選取「reCAPTCHA v2」和「reCAPTCHA Android」
    • 套件:如有使用此 API 金鑰的應用程式,請提供每個應用程式的套件名稱。為了讓應用程式使用 API,您輸入的套件名稱必須與應用程式的套件名稱完全相符。請每行輸入一個套件名稱。
    • 擁有者:為貴機構中負責監控應用程式 reCAPTCHA 評估作業的每位人員,新增電子郵件地址。
  2. 勾選「接受《reCAPTCHA 服務條款》」核取方塊。

  3. 傳送通知給擁有者:如要接收 reCAPTCHA API 的相關電子郵件,請勾選這個核取方塊,然後按一下「提交」

  4. 在下一個顯示的頁面中,您的公開和私密金鑰分別會顯示在「網站金鑰」和「密鑰」部分。傳送驗證要求時,請使用網站金鑰,而驗證使用者回應權杖時,則需使用密鑰。

新增 SafetyNet API 依附元件

使用 reCAPTCHA API 前,請先在專案中新增 SafetyNet API。如果您使用的是 Android Studio,請將這個依附元件新增至應用程式層級的 Gradle 檔案。詳情請參閱「SafetyNet API 設定」。

使用 reCAPTCHA API

本節說明如何呼叫 reCAPTCHA API,用於傳送人機驗證 (CAPTCHA) 驗證要求及接收使用者回應權杖。

傳送驗證要求

如要叫用 SafetyNet reCAPTCHA API,請呼叫 verifyWithRecaptcha() 方法。一般來說,這個方法會對應使用者在活動中選取的 UI 元素 (例如按鈕)。

在應用程式中使用 verifyWithRecaptcha() 方法時,請務必採取以下做法:

  • 傳入 API 網站金鑰做為參數。
  • 覆寫 onSuccess()onFailure() 方法,以便處理驗證要求工作中兩種可能的結果。請務必留意,如果 API 將 ApiException 的例項傳遞至 onFailure(),您必須處理每個可能出現的狀態碼。您可以使用 getStatusCode() 擷取這些狀態碼。

下列程式碼片段說明如何叫用這個方法:

Kotlin

fun onClick(view: View) {
    SafetyNet.getClient(this).verifyWithRecaptcha(YOUR_API_SITE_KEY)
            .addOnSuccessListener(this as Executor, OnSuccessListener { response ->
                // Indicates communication with reCAPTCHA service was
                // successful.
                val userResponseToken = response.tokenResult
                if (response.tokenResult?.isNotEmpty() == true) {
                    // Validate the user response token using the
                    // reCAPTCHA siteverify API.
                }
            })
            .addOnFailureListener(this as Executor, OnFailureListener { e ->
                if (e is ApiException) {
                    // An error occurred when communicating with the
                    // reCAPTCHA service. Refer to the status code to
                    // handle the error appropriately.
                    Log.d(TAG, "Error: ${CommonStatusCodes.getStatusCodeString(e.statusCode)}")
                } else {
                    // A different, unknown type of error occurred.
                    Log.d(TAG, "Error: ${e.message}")
                }
            })
}

Java

public void onClick(View v) {
    SafetyNet.getClient(this).verifyWithRecaptcha(YOUR_API_SITE_KEY)
        .addOnSuccessListener((Executor) this,
            new OnSuccessListener<SafetyNetApi.RecaptchaTokenResponse>() {
                @Override
                public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response) {
                    // Indicates communication with reCAPTCHA service was
                    // successful.
                    String userResponseToken = response.getTokenResult();
                    if (!userResponseToken.isEmpty()) {
                        // Validate the user response token using the
                        // reCAPTCHA siteverify API.
                    }
                }
        })
        .addOnFailureListener((Executor) this, new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    if (e instanceof ApiException) {
                        // An error occurred when communicating with the
                        // reCAPTCHA service. Refer to the status code to
                        // handle the error appropriately.
                        ApiException apiException = (ApiException) e;
                        int statusCode = apiException.getStatusCode();
                        Log.d(TAG, "Error: " + CommonStatusCodes
                                .getStatusCodeString(statusCode));
                    } else {
                        // A different, unknown type of error occurred.
                        Log.d(TAG, "Error: " + e.getMessage());
                    }
                }
        });
}

驗證使用者回應權杖

reCAPTCHA API 執行 onSuccess() 方法時,使用者已成功回答人機驗證 (CAPTCHA) 問題。不過,這個方法只是表示使用者已正確回答人機驗證問題。您仍然需要從後端伺服器驗證使用者的回應權杖。

如要瞭解如何驗證使用者的回應權杖,請參閱「驗證使用者的回應」。