Advertisement
  1. Code
  2. Mobile Development
  3. Android Development

Как добавить CAPTCHA в приложения для Android

Scroll to top
Read Time: 8 min

() translation by (you can also view the original English article)

Если вы разрабатываете приложение для Android, которое должно взаимодействовать с вашим внутренним сервером, важно принять меры для его защиты от автоматизированных скриптовых ботов, которые пытаются выдавать себя для человека. В противном случае ваш сервер может быть ими атакован.

CAPTCHA, сокращение от Completely Automated Public Turing tests for telling Computers and Humans Apart, в настоящее время является наиболее эффективной защитой от ботов. Как вы, возможно, уже знаете, они обычно представляют собой образ, голос или тесты на основе здравого смысла, которые легко доступны для людей, но чрезвычайно сложны для компьютеров.

В этом уроке я покажу вам, как использовать недавно выпущенный API reCAPTCHA для добавления CAPTCHA в ваши приложения для Android.

Предпосылки

Чтобы иметь возможность следовать этой статье, вам понадобится следующее:

1. Настройка проекта

Запустите Android Studio и создайте новый проект с пустым действием. В настройке нового проекта убедитесь, что вы вводите осмысленное имя пакета - вы будете использовать его при регистрации своего приложения с помощью службы reCAPTCHA.

Кроме того, установите флажок Включить поддержку Kotlin. Поскольку Kotlin теперь является официальным языком Android, в этом учебнике мы будем использовать его вместо Java.

Configure your new project formConfigure your new project formConfigure your new project form

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 registration formreCAPTCHA registration formreCAPTCHA registration form

После того, как вы примете условия обслуживания reCAPTCHA, нажмите кнопку Зарегистрироваться, чтобы сгенерировать оба ключа.

Site key and secret key screenSite key and secret key screenSite key and secret key screen

Теперь вы можете добавить ключ сайта в свой проект Android Studio, просто указав его внутри файла res/values/strings.xml:

1
<string name="my_site_key">ABCDEFGHIJKLMNOPQ1234567890</string>

Мы будем работать с секретным ключом только в конце этого урока, поэтому запишите его сейчас в безопасное место.

3. Создание CAPTCHA

Когда мы слышим слово CAPTCHA, мы обычно думаем о грязных изображениях, содержащих трудночитаемые буквы и цифры. Однако такие CAPTCHA, благодаря достижениям в области технологий компьютерного зрения, уже недостаточно хороши, чтобы остановить всех ботов.

CAPTCHA, созданные службой reCAPTCHA, очень продвинуты и очень интерактивны. Фактически, их решение сродни игре в простые игры. Следовательно, вы не можете напрямую вставлять их в макет своей деятельности. Вместо этого вы должны добавить кнопку в макет, при нажатии на которую пользователь должен увидеть новый экран или диалоговое окно, содержащее CAPTCHA.

В следующем коде показано, как добавить виджет Button в XML-файл макета вашей деятельности:

1
<Button
2
    android:id="@+id/are_you_human_button"
3
    android:layout_width="wrap_content"
4
    android:layout_height="wrap_content"
5
    android:layout_centerHorizontal="true"
6
    android:layout_centerVertical="true"
7
    android:text="Are you human?" />

Прежде чем вы начнете генерировать CAPTCHA, вам придется инициализировать клиент для API SafetyNet. Вы можете сделать это, вызвав метод getClient() класса SafetyNet. Соответственно, добавьте следующий код внутри метода onCreate() вашего класса Activity:

1
val myClient: SafetyNetClient = SafetyNet.getClient(this)

CAPTCHA должна отображаться, когда пользователь нажимает кнопку, поэтому добавьте обработчик события on-click к нему, используя метод setOnClickListener(). Внутри обработчика все, что вам нужно сделать, это вызвать метод verifyWithRecaptcha() и передать ключ вашего сайта в качестве аргумента, чтобы открыть диалог, содержащий CAPTCHA.

Возвращаемое значение метода verifyWithRecaptcha() является объектом Task. Присоединив к нему обработчик события on-success, вы сможете получить объект RecaptchaTokenResponse, содержащий токен, который вы можете использовать, чтобы указать, прошел ли пользователь или не прошел CAPTCHA:

1
are_you_human_button.setOnClickListener {
2
    myClient
3
    .verifyWithRecaptcha(resources.getString(R.string.my_site_key))
4
    .addOnSuccessListener { successEvent ->
5
        val token: String = successEvent.tokenResult
6
7
        // More code here

8
    }
9
}

4. Проверка токенов CAPTCHA

Токен, полученный на предыдущем шаге, должен снова быть передан службе reCAPTCHA, чтобы проверить, прошел ли пользователь или не прошел тест. Однако на этот раз вызов службы reCAPTCHA должен быть сделан с вашего внутреннего сервера.

Разумеется, сервер не будет иметь токен, если ваше приложение Android не отправит его ему. Поэтому теперь мы должны написать код для отправки токенов из приложения Android на сервер.

Пока давайте предположим, что наш сервер имеет конечную точку под названием validate, которая может принимать токен в качестве параметра строки запроса. Я буду использовать 10.0.2.2 в качестве IP-адреса сервера и 8000 в качестве порта. Если вы собираетесь запускать сервер на своем компьютере и в приложении на эмуляторе, запущенном на том же компьютере, вы также можете использовать один и тот же IP-адрес.

1
val serverURL: String = "https://10.0.2.2:8000/validate"

Теперь вы можете вызвать метод httpGet() библиотеки Fuel, чтобы отправить токен на сервер. Метод ожидает, что список параметров строки запроса будет единственным аргументом, поэтому я предлагаю вам использовать метод утилиты listOf() для создания списка, содержащего один элемент: токен, назначенный параметру запроса с именем user_token.

Поскольку метод httpGet() выполняется асинхронно, вы должны вызвать метод responseString() для обработки возвращаемого значения. В следующем коде показано, как это сделать:

1
serverURL.httpGet(listOf("user_token" to token))
2
    .responseString { request, response, result ->
3
        // More code here

4
    }

Вы можете видеть, что теперь у нас есть доступ к объекту result. В случае отсутствия ошибок он будет содержать ответ нашего сервера в виде строки.

Предположим, что наш сервер возвращает строку «PASS», если пользователь проходит тест, и «FAIL» в противном случае. То, что вы на самом деле делаете, когда пользователь проходит или не проходит тест, конечно, зависит от вас. Пока я предлагаю вам просто отображать соответствующие сообщения Toast. Следующий код показывает вам, как сделать это кратко:

1
result.fold({ data ->
2
    if(data.contains("PASS"))
3
        Toast.makeText(baseContext,
4
                "You seem to be a human.",
5
                Toast.LENGTH_LONG).show()
6
    else
7
        Toast.makeText(baseContext,
8
                "You seem to be a bot!",
9
                Toast.LENGTH_LONG).show()
10
}, { error ->
11
    Log.d("ERROR", "Error connecting to the server")
12
})

На данный момент приложение готово. Вы можете продолжить и развернуть его на свой эмулятор или устройство.

CAPTCHA dialog shown when user presses the buttonCAPTCHA dialog shown when user presses the buttonCAPTCHA dialog shown when user presses the button

5. Создание сервера

Мы уже сделали несколько предположений о нашем веб-сервере на более ранних этапах. Настало время создать его, убедившись, что он не отклоняется от этих предположений.

Быстрый и простой способ создания полностью функционального веб-сервера - использовать платформу Node.js и фреймворк Express.js. Чтобы создать новый проект Node.js, создайте новый каталог на своем компьютере и запустите в нем команду npm init.

1
mkdir my_web_server
2
cd my_web_server ; npm init -y

Чтобы добавить фреймворк Express к проекту, вы можете использовать команду npm install.

1
npm install --save express

Кроме того, нам понадобится пакет Request для связи с сервисом reCAPTCHA. Поэтому установите его как зависимость.

1
npm install --save request

Теперь вы можете использовать свой любимый редактор кода для создания нового файла с именем index.js и начать писать необходимый код на стороне сервера.

Начните с загрузки модулей express и request с помощью функции require() и создания нового Express-приложения, вызвав функцию express().

1
const express = require('express');
2
const request = require('request');
3
4
const myApp = express();

У нашего экспресс-приложения должна быть конечная точка, называемая validate, к которой можно получить доступ, используя метод HTTP GET. Поэтому создайте для него новый маршрут, используя метод get():

1
myApp.get('/validate', function(req, resp) {
2
    // More code here

3
});

Чтобы проверить токен, созданный приложением Android, вы должны теперь сделать запрос POST службе reCAPTCHA. Запрос должен содержать ваш секретный ключ и сам токен. В следующем коде показано, как создать тело запроса POST, извлекая токен из строки запроса:

1
const postData = {
2
    secret: '1234567890-abcdefghijklmnopqr',
3
    response: req.query.user_token
4
};

Чтобы действительно выполнить запрос POST, вы можете вызвать метод post() модуля request. Его ответ - это короткий документ JSON, содержащий ключ success. Как и следовало ожидать, его значение будет true, только если пользователь прошел проверку

Следующий код показывает вам, как разбирать документ JSON, извлекать ключ success и генерировать ответы «PASS» и «FAIL», которые требуется нашим приложениям для Android:

1
request.post({
2
    url: 'https://www.google.com/recaptcha/api/siteverify',
3
  form: postData
4
}, function(error, response, body) {
5
	jsonData = JSON.parse(body); // Parse the JSON document

6
    
7
	if(jsonData.success) { // User passed the test

8
		resp.send('PASS');
9
	} else { // User didn't pass the test

10
		resp.send('FAIL');
11
	}
12
    
13
});

Наконец, вы должны вызвать метод listen() объекта приложения Express, чтобы он мог прослушивать соединения.

1
myApp.listen(8000);

На этом этапе наш веб-сервер готов. Чтобы запустить его, вернитесь к терминалу и выполните следующую команду:

1
node index.js

Если вы запустите приложение Android сейчас, нажмите кнопку и успешно разрешите CAPTCHA, вы увидите сообщение Toast, сообщающее вам, что вы человек.

Toast message shown when user passes the CAPTCHAToast message shown when user passes the CAPTCHAToast message shown when user passes the CAPTCHA

Заключение

Теперь вы знаете, как использовать API-интерфейс SafetyNet reCAPTCHA для защиты вашего приложения Android и внутренней инфраструктуры от ботов. Вам больше не нужно беспокоиться об автоматизированных регистрациях, скриншотах экрана или спаме, созданных ботом.

Чтобы узнать больше о API reCAPTCHA, вы можете обратиться к официальной документации.

Тем временем, ознакомьтесь с некоторыми из наших замечательных статей о разработке приложений для Android!

Advertisement
Did you find this post useful?
Want a weekly email summary?
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.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.