Если вы разрабатываете приложение для Android, которое должно взаимодействовать с вашим внутренним сервером, важно предпринять шаги, чтобы защитить его от ботов — автоматических сценариев, которые пытаются передать человеку. В противном случае ваш сервер имеет очень реальный шанс быть захваченным ими.
CAPTCHA, сокращенно от «Полностью автоматизированных тестов Public Turing» для рассказа «Компьютеры и люди отдельно», в настоящее время являются наиболее эффективной защитой от ботов. Как вы, возможно, уже знаете, это обычно тесты на основе изображений, голоса или здравого смысла, которые удобны для человека, но чрезвычайно сложны для компьютеров.
В этом руководстве я покажу вам, как использовать недавно выпущенный API-интерфейс SafetyNet reCAPTCHA для добавления CAPTCHA в ваши приложения Android.
Предпосылки
Чтобы следовать этому уроку, вам понадобится следующее:
- Android Studio 3.0 Canary 4 или выше
- устройство или эмулятор под управлением Android 4.4 или выше
- Node.js 8.1.3 или выше
1. Настройка проекта
Запустите Android Studio и создайте новый проект с пустым действием. В форме « Настройка нового проекта» обязательно введите значимое имя пакета — оно будет использоваться при регистрации приложения в службе reCAPTCHA.
Кроме того, установите флажок Включить поддержку Kotlin . Поскольку Kotlin теперь является официальным языком Android, мы будем использовать его вместо Java в этом руководстве.
API SafetyNet являются частью сервисов Google Play. Чтобы иметь возможность использовать их в своем проекте, добавьте следующую зависимость implementation
в файл build.gradle модуля app
:
1
|
implementation ‘com.google.android.gms:play-services-safetynet:11.0.2’
|
Кроме того, для выполнения сетевых операций мы будем использовать библиотеку Fuel , которая имеет очень лаконичный API на основе Kotlin. Поэтому добавьте его как еще одну зависимость implementation
.
1
|
implementation ‘com.github.kittinunf.fuel:fuel-android:1.8.0’
|
Вы не можете выполнять сетевые операции без разрешения INTERNET
, поэтому добавьте следующую строку в файл манифеста вашего проекта:
1
|
<uses-permission android:name=»android.permission.INTERNET»/>
|
Наконец, нажмите кнопку « Синхронизировать сейчас» , чтобы завершить настройку проекта.
2. Получение ключей reCAPTCHA
Вам понадобятся два ключа, прежде чем вы сможете использовать сервис reCAPTCHA:
- ключ сайта, который необходимо передать службе из вашего приложения для Android
- и секретный ключ, который необходимо передать службе с вашего внутреннего сервера
Чтобы получить ключи, используйте свою учетную запись Google и войдите в консоль администратора reCAPTCHA. Если вы открываете консоль в первый раз, вам автоматически будет предоставлена короткая форма регистрации, в которой вы сможете ввести имя пакета вашего приложения.
После того, как вы примете условия обслуживания reCAPTCHA, продолжайте и нажмите кнопку Register , чтобы сгенерировать оба ключа.
Теперь вы можете добавить ключ сайта в свой проект Android Studio, просто упомянув его в файле res / values / strings.xml :
1
|
<string name=»my_site_key»>ABCDEFGHIJKLMNOPQ1234567890</string>
|
Мы будем работать с секретным ключом только ближе к концу этого урока, поэтому запишите его в безопасное место.
3. Генерация капчей
Когда мы слышим слово CAPTCHA, мы обычно думаем о грязных изображениях, содержащих трудно читаемые буквы и цифры. Однако такие капчи, благодаря достижениям в технологиях компьютерного зрения, уже недостаточно хороши, чтобы остановить всех ботов.
CAPTCHA, генерируемые сервисом reCAPTCHA, очень продвинуты и очень интерактивны. На самом деле, их решение сродни игре в простые игры. Следовательно, вы не можете напрямую встраивать их в макет своей деятельности. Вместо этого вы должны добавить кнопку в макет, который при нажатии должен привести пользователя к новому экрану или диалоговому окну, содержащему CAPTCHA.
Следующий код показывает, как добавить виджет Button
в XML-файл макета вашей деятельности:
1
2
3
4
5
6
7
|
<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?»
|
Прежде чем вы начнете генерировать CAPTCHA, вам нужно будет инициализировать клиент для API SafetyNet. Вы можете сделать это, вызвав метод getClient()
класса SafetyNet
. Соответственно, добавьте следующий код в метод onCreate()
вашего класса Activity
:
1
|
val myClient: SafetyNetClient = SafetyNet.getClient(this)
|
CAPTCHA должны отображаться, когда пользователь нажимает кнопку, поэтому добавьте в нее обработчик события щелчка, используя метод setOnClickListener()
. Внутри обработчика все, что вам нужно сделать, это вызвать метод verifyWithRecaptcha()
и передать ключ сайта в качестве аргумента, чтобы открыть диалог, содержащий CAPTCHA.
Возвращаемое значение метода verifyWithRecaptcha()
является объектом Task
. RecaptchaTokenResponse
к нему обработчик события при успехе, вы сможете получить объект RecaptchaTokenResponse
содержащий токен, который вы можете использовать, чтобы определить, прошел ли пользователь CAPTCHA или нет. Вот как:
1
2
3
4
5
6
7
8
9
|
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 не отправит его на него. Поэтому теперь мы должны написать код для отправки токенов из приложения Android на сервер.
А пока давайте предположим, что у нашего сервера есть конечная точка с именем validate
, которая может принять токен в качестве параметра строки запроса. Я буду использовать 10.0.2.2 в качестве IP-адреса сервера и 8000 в качестве его порта. Если вы намерены запустить сервер на своем компьютере и приложение на эмуляторе, работающем на одном компьютере, вы также можете использовать один и тот же IP-адрес.
1
|
val serverURL: String = «http://10.0.2.2:8000/validate»
|
Теперь вы можете вызвать метод httpGet()
предлагаемый библиотекой Fuel, чтобы отправить токен на сервер. Метод ожидает список параметров строки запроса в качестве единственного аргумента, поэтому я предлагаю вам использовать служебный метод listOf()
для создания списка, содержащего один элемент: токен, назначенный параметру запроса с именем user_token
.
Поскольку метод httpGet()
выполняется асинхронно, необходимо обработать метод responseString()
для обработки его возвращаемого значения. Следующий код показывает вам, как:
1
2
3
4
|
serverURL.httpGet(listOf(«user_token» to token))
.responseString { request, response, result ->
// More code here
}
|
Вы можете видеть, что теперь у нас есть доступ к объекту result
. В случае отсутствия ошибок, он будет содержать ответ нашего сервера в виде строки.
Предположим, что наш сервер возвращает строку «PASS», если пользователь проходит тест, и «FAIL» в противном случае. Что вы на самом деле делаете, когда пользователь проходит или не проходит тест, конечно, зависит от вас. На данный момент я предлагаю вам просто отобразить соответствующие сообщения Toast
. Следующий код показывает, как сделать это кратко:
01
02
03
04
05
06
07
08
09
10
11
12
|
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»)
})
|
На данный момент приложение готово. Вы можете пойти дальше и развернуть его на своем эмуляторе или устройстве.
5. Создание сервера
Мы сделали много предположений о нашем веб-сервере на предыдущих этапах. Пришло время создать его, убедившись, что он не отклоняется от этих предположений.
Быстрый и простой способ создания полнофункционального веб-сервера — это использование платформы Node.js и платформы Express.js . Чтобы создать новый проект Node.js, создайте новый каталог на своем компьютере и выполните в нем команду npm init
.
1
2
|
mkdir my_web_server
cd my_web_server ;
|
Чтобы добавить платформу Express в проект, вы можете использовать команду npm install
.
1
|
npm install —save express
|
Кроме того, нам потребуется пакет Request для связи со службой reCAPTCHA. Поэтому установите его как другую зависимость.
1
|
npm install —save request
|
Теперь вы можете использовать ваш любимый редактор кода, чтобы создать новый файл с именем index.js и начать писать весь необходимый код на стороне сервера.
Начните с загрузки модулей express
и request
с помощью функции require()
и создания нового приложения Express, вызвав функцию express()
.
1
2
3
4
|
const express = require(‘express’);
const request = require(‘request’);
const myApp = express();
|
Наше приложение Express должно иметь конечную точку с именем validate
, к которой можно получить доступ с помощью метода HTTP GET. Поэтому создайте для него новый маршрут, используя метод get()
:
1
2
3
|
myApp.get(‘/validate’, function(req, resp) {
// More code here
});
|
Чтобы проверить токен, сгенерированный приложением Android, вы должны сделать POST-запрос к сервису reCAPTCHA. Запрос должен содержать ваш секретный ключ и сам токен. Следующий код показывает, как построить тело запроса POST, извлекая токен из строки запроса:
1
2
3
4
|
const postData = {
secret: ‘1234567890-abcdefghijklmnopqr’,
response: req.query.user_token
};
|
Чтобы фактически сделать запрос POST, вы можете вызвать метод post()
модуля request
. Его ответ — это короткий JSON-документ, содержащий ключ с именем success
. Как и следовало ожидать, его значение true
только если пользователь прошел тест.
В следующем коде показано, как выполнить синтаксический анализ документа JSON, извлечь ключ success
и сгенерировать ответы «PASS» и «FAIL», необходимые для приложения Android:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
request.post({
url: ‘https://www.google.com/recaptcha/api/siteverify’,
form: postData
}, function(error, response, body) {
jsonData = JSON.parse(body);
if(jsonData.success) { // User passed the test
resp.send(‘PASS’);
} else { // User didn’t pass the test
resp.send(‘FAIL’);
}
});
|
Наконец, вы должны вызвать метод listen()
объекта приложения Express, чтобы он мог прослушивать соединения.
1
|
myApp.listen(8000);
|
На данный момент наш веб-сервер готов. Чтобы запустить его, вернитесь в терминал и выполните следующую команду:
1
|
node index.js
|
Если вы запустите приложение Android сейчас, нажмите кнопку и успешно решите CAPTCHA, вы должны увидеть сообщение Toast
сообщающее, что вы человек.
Вывод
Теперь вы знаете, как использовать API-интерфейс SafetyNet reCAPTCHA для защиты приложения Android и внутренней инфраструктуры от ботов. Вам больше не нужно беспокоиться об автоматических регистрациях, скребках экрана или спаме, генерируемом ботами.
Чтобы узнать больше об API reCAPTCHA, вы можете обратиться к официальной документации .
А пока ознакомьтесь с другими нашими замечательными статьями по разработке приложений для Android!