Chinese (Traditional) (中文(繁體)) translation by tianma (you can also view the original English article)
如果你正在開發需要與後端伺服器進行交互的Android APP,那麼你必須採取措施來與bots對抗,bots是自動化的腳本,這種腳本嘗試假扮人類以通過驗證。否則的話,你的伺服器可能因頻繁過度訪問而崩潰。
CAPTCHAs(Completely Automated Public Turing tests for telling Computers and Humans Apart的簡寫)目前是防禦bots的最有效方式。你可能已經知道,它們通常是對人類很容易的圖像,語音或常識測試,但這種測試對電腦卻非常困難。
在本教程中,我將展示如何使用新發佈的SafetyNet reCAPTCHA API將CAPTCHAs添加到你的Android APP。
準備工作
為了保持與本文的一致,你需要下列內容:
- Android Studio 3.0 Canary 4或更高版本
- 運行Android 4.4或更高版本的設備或模擬器
- Node.js 8.1.3或更高版本
1.專案設置
啟動Android Studio並創建帶有空activity的新專案。在配置新的專案的表單中,確保輸入有意義的包名稱 - 因為這個包名會在使用reCAPTCHA服務註冊APP時使用。
另外,勾選Include Kotlin Support。因為Kotlin現在是Android官方語言,所以我們將在本教程中使用它而不是Java。

SafetyNet API是Google Play服務的一部分。要在項目中使用它們,請將以下implementation
依賴項添加到app
module級的build.gradle文件中:
implementation 'com.google.android.gms:play-services-safetynet:11.0.2'
另外,我們將使用Fuel庫來執行與網路相關的操作,該庫具有非常簡潔的基於Kotlin的API。因此,將其添加為另一個 implementation
依賴項。
implementation 'com.github.kittinunf.fuel:fuel-android:1.8.0'
因為有網路相關的操作,我們需要添加INTERNET
許可權,因此請將以下行添加到專案的清單檔中:
<uses-permission android:name="android.permission.INTERNET"/>
最後,點擊“ 立即同步” 按鈕完成專案配置。
2.獲取reCAPTCHA鍵
你需要兩個金鑰才能使用reCAPTCHA服務:
- 一個網站金鑰,必須從你Android APP傳遞給該服務
- 一個秘密金鑰,必須從後端伺服器傳遞給服務
要獲取金鑰,請使用你的Google帳戶登錄到reCAPTCHA管理主控台。如果你是第一次打開控制台,則會自動顯示一個簡短的註冊表單,您可以在其中輸入應用的包名稱。

你接受reCAPTCHA服務條款後,請繼續按“ 註冊”按鈕生成兩個金鑰。
.png)
將網站金鑰添加到res/values/strings.xml檔,即將網站金鑰添加到Android Studio專案中。
<string name="my_site_key">ABCDEFGHIJKLMNOPQ1234567890</string>
我們將在本教程結尾處使用秘密金鑰,所以你需要把秘密金鑰放在安全的地方。
3.生成CAPTCHAs
當我們聽到CAPTCHA這個詞時,我們通常會想到難以讀取的字母和數位。然而,由於電腦視覺技術的進步,這樣的CAPTCHAs已經無法阻止所有bots了。
由reCAPTCHA服務產生的CAPTCHA是非常先進和可交互的。事實上,通過它們的驗證類似於玩簡單的遊戲。 因此,你無法直接將其添加到activity的佈局檔中。你必須在佈局中添加一個按鈕,當按下該按鈕時,應該將使用者引導到包含CAPTCHA的新介面或對話方塊。
以下代碼顯示了如何向XML佈局檔中添加Button
控制項:
<Button android:id="@+id/are_you_human_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="Are you human?" />
在開始生成CAPTCHAs之前,你必須初始化SafetyNet API的用戶端。 你可以調用SafetyNet
類的getClient()
方法來實現。在Activity
類的onCreate()
方法中添加以下代碼:
val myClient: SafetyNetClient = SafetyNet.getClient(this)
當使用者按下按鈕時,CAPTCHA必須顯示,所以使用setOnClickListener()
方法添加一個點擊事件來處理。在處理常式中,你需要做的就是調用verifyWithRecaptcha()
方法,並將網站金鑰作為參數傳遞給它,以便打開包含人機驗證碼的對話方塊。
verifyWithRecaptcha()
方法返回一個Task
物件。 通過將一個成功的事件處理常式附加到它,你將獲取一個包含權杖的RecaptchaTokenResponse
物件,你可以使用該物件來判斷使用者是否通過了CAPTCHA或失敗了。過程如下:
are_you_human_button.setOnClickListener { myClient .verifyWithRecaptcha(resources.getString(R.string.my_site_key)) .addOnSuccessListener { successEvent -> val token: String = successEvent.tokenResult // More code here } }
4.驗證CAPTCHA權杖
你在上一步中獲得的權杖必須再次傳遞給reCAPTCHA服務,以檢查使用者是否通過或未通過測試。但是,這次必須由後端伺服器調用reCAPTCHA服務。
伺服器當然不會有權杖,除非你的Android APP發送給它了。因此,我們現在必須編寫代碼,將Android APP的權杖發送到伺服器。
現在,假設我們的伺服器有一個叫validate
的端點,它可以接受權杖作為查詢字串參數。我將使用10.0.2.2作為伺服器的IP位址,8000作為埠。 如果你打算在自己的電腦上運行伺服器並在同一台電腦上運行的模擬器上運行該APP,那麼也可以使用相同的IP位址。
val serverURL: String = "https://10.0.2.2:8000/validate"
你現在可以調用Fuel庫提供的httpGet()
方法將權杖發送到伺服器。該方法期望查詢字串參數清單作為其唯一參數,因此建議你使用listOf()
方法創建一個包含單個專案的列表,那單個項目為:分配給查詢參數名為user_token
的權杖。
因為httpGet()
方法是非同步運行的,你必須調用responseString()
方法才能處理其返回值。步驟如下:
serverURL.httpGet(listOf("user_token" to token)) .responseString { request, response, result -> // More code here }
你可以看到我們現在可以訪問一個result
物件。如果沒有錯誤,它將包含伺服器回應的字串。
如果用戶通過測試,我們的伺服器返回“PASS”字串,否則返回“FAIL”字串。當使用者通過測試或失敗時,你可以根據自己的需要做相應的處理。 現在,我建議你顯示相應的Toast
消息。代碼實現:
result.fold({ data -> if(data.contains("PASS")) Toast.makeText(baseContext, "You seem to be a human.", Toast.LENGTH_LONG).show() else Toast.makeText(baseContext, "You seem to be a bot!", Toast.LENGTH_LONG).show() }, { error -> Log.d("ERROR", "Error connecting to the server") })
現在,APP已經準備就緒。你可以運行了。

5.創建伺服器
在較早的步驟中,我們對Web伺服器做了很多假設。在前面那些假設的前提下,開始創建它吧。
快捷方便地創建功能齊全的Web伺服器的方法是使用Node.js平臺和Express.js框架。想要創建一個新的Node.js專案,先在電腦上創建一個新目錄並運行npm init
。
mkdir my_web_server cd my_web_server ; npm init -y
要將Express框架添加到項目中,可以使用npm install
命令。
npm install --save express
另外,我們需要Request包來與reCAPTCHA服務進行通信。因此,添加對Request包的依賴。
npm install --save request
你現在可以使用自己喜歡的代碼編輯器來創建一個名為index.js的新檔, 並開始編寫伺服器端代碼。
首先載入express
和request
模組,後者使用了require()
方法,然後通過調用express()
方法創建一個新的Express應用程式。
const express = require('express'); const request = require('request'); const myApp = express();
我們的Express應用程式必須具有一個叫validate
的端點,這個端點可以通過HTTP GET方法來訪問。因此,使用get()
方法來創建新路由 :
myApp.get('/validate', function(req, resp) { // More code here });
要驗證Android應用生成的權杖,你必須向reCAPTCHA服務發出POST請求。該請求必須包含你的金鑰和權杖本身。 以下代碼展示了通過從查詢字串中提取權杖來構建POST請求體:
const postData = { secret: '1234567890-abcdefghijklmnopqr', response: req.query.user_token };
要進行真正的POST請求,可以調用request
模組中post()
方法 。伺服器響應是一個包含success鍵的短JSON文檔。機智如你,如果用戶通過了測試,該success
鍵的值才為true
。
以下代碼顯示了如何解析JSON文檔,提取success
鍵,並生成Android APP需要的“PASS”和“FAIL”回應:
request.post({ url: 'https://www.google.com/recaptcha/api/siteverify', form: postData }, function(error, response, body) { jsonData = JSON.parse(body); // Parse the JSON document if(jsonData.success) { // User passed the test resp.send('PASS'); } else { // User didn't pass the test resp.send('FAIL'); } });
最後,你必須調用Express應用程式物件的listen()
方法來監聽連接。
myApp.listen(8000);
現在我們的web伺服器已經準備好了。開啟伺服器,在終端輸入如下命令:
node index.js
如果你現在運行了Android APP,請點擊按鈕,並成功通過人機驗證,然後你應該會看到一條Toast
消息,告訴你是人操作而不是機器操作的。

結語
你現在知道如何使用SafetyNet reCAPTCHA API來保護你的Android APP和後端基礎設施免受bots攻擊了。你再也不必擔心自動註冊,介面卡頓或bots產生的垃圾郵件了。
想瞭解有關reCAPTCHA API的更多資訊,請參閱官方文檔。
與此同時,請查看關於Android APP開發的其他文章!
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post