Advertisement
  1. Code
  2. Android SDK

Cómo añadir CAPTCHAs a aplicaciones Android

Scroll to top
Read Time: 9 min

Spanish (Español) translation by Ana Paulina Figueroa (you can also view the original English article)

Si estás desarrollando una aplicación Android que necesite interactuar con tu servidor back-end, es importante que tomes medidas para defenderlo de bots y secuencias de comandos automatizadas que intentan hacerse pasar por humanos. De lo contrario existe una posibilidad muy real de que tu servidor sea invadido por ellos.

Los CAPTCHA, abreviación de Completely Automated Public Turing tests for telling Computers and Humans Apart (Prueba de Turing completamente automática y pública para diferenciar computadoras de humanos), son la defensa más efectiva contra los bots en la actualidad. Como quizá ya sepas, generalmente son pruebas con imágenes, voz o de sentido común que son fáciles para los humanos, pero extremadamente difíciles para las computadoras.

En este tutorial te enseñaré cómo usar la recientemente lanzada API reCAPTCHA de SafetyNet para añadir CAPTCHAs a tus aplicaciones Android.

Requisitos previos

Para poder seguir este tutorial necesitarás lo siguiente:

1. Configuración del proyecto

Ejecuta Android Studio y crea un nuevo proyecto con una activity vacía. En el formulario Configure your new project (Configura tu nuevo proyecto) asegúrate de escribir un nombre de paquete significativo, ya que lo usarás al registrar tu aplicación con el servicio de reCAPTCHA.

Además marca la casilla Include Kotlin Support (Incluir soporte para Kotlin). Ahora Kotlin es un lenguaje oficial de Android, por lo que en este tutorial lo usaremos en vez de Java.

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

Las APIs de SafetyNet son parte de los servicios de Google Play. Para poder usarlas en tu proyecto, agrega la siguiente dependencia implementation al archivo build.gradle del módulo app:

1
implementation 'com.google.android.gms:play-services-safetynet:11.0.2'

Además, para llevar a cabo operaciones relacionadas con la red usaremos la biblioteca Fuel, que tiene una API muy concisa basada en Kotlin. Por lo tanto agrégala como otra dependencia implementation.

1
implementation 'com.github.kittinunf.fuel:fuel-android:1.8.0'

No puedes llevar a cabo operaciones relacionadas con la red sin el permiso INTERNET, así que agrega la siguiente línea al archivo manifiesto de tu proyecto:

1
<uses-permission android:name="android.permission.INTERNET"/>

Finalmente presiona el botón Sync Now (Sincronizar ahora) para terminar la configuración del proyecto.

2. Adquiriendo claves de reCAPTCHA

Necesitarás dos claves antes de poder usar el servicio reCAPTCHA:

  • Una clave de sitio, que debe ser enviada al servicio desde tu aplicación Android
  • y una clave secreta, que debe ser enviada al servicio desde tu servidor back-end

Para obtener las claves usa tu cuenta de Google e inicia sesión en la consola de administración de reCAPTCHA. Si estás abriendo la consola por primera vez, ésta te mostrará automáticamente un pequeño formulario de registro en el que puedes escribir el nombre de paquete de tu aplicación.

reCAPTCHA registration formreCAPTCHA registration formreCAPTCHA registration form

Después de aceptar los términos de servicio de reCAPTCHA, continúa presionando el botón Register (Registrar) para generar ambas claves.

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

Ahora puedes agregar la clave de sitio a tu proyecto de Android Studio simplemente mencionándola dentro del archivo res/values/strings.xml:

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

Vamos a trabajar con la clave secreta solamente cerca del final de este tutorial, así que anótala en algún lugar seguro por ahora.

3. Generando CAPTCHAs

Cuando escuchamos la palabra CAPTCHA usualmente pensamos en imágenes desordenadas que contienen letras y números difíciles de leer. Sin embargo, gracias a los avances en las tecnologías de visión por computadora, tales CAPTCHAs ya no son lo suficientemente buenos para detener a todos los bots.

Los CAPTCHAs generados por el servicio reCAPTCHA son altamente avanzados y muy interactivos también. De hecho, resolverlos es similar a jugar juegos simples. En consecuencia no puedes incrustarlos directamente en el diseño de tu activity. En vez de eso debes añadir un botón al diseño que, al ser presionado, deberá dirigir al usuario a una nueva pantalla o cuadro de diálogo que contenga los CAPTCHAs.

El siguiente código te muestra cómo añadir un widget Button al archivo XML de diseño de tu activity:

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?" />

Antes de comenzar a generar CAPTCHAs tendrás qué inicializar un cliente para la API de SafetyNet. Puedes hacerlo invocando al método getClient() de la clase SafetyNet. De acuerdo con esto, agrega el siguiente código dentro del método onCreate() de tu clase Activity:

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

Los CAPTCHAs deben mostrarse cuando el usuario presione el botón, así que agrégale un manejador para el evento on-click usando el método setOnClickListener(). Dentro del manejador, todo lo que tienes que hacer es invocar al método verifyWithRecaptcha() y enviarle tu clave de sitio como argumento para abrir un cuadro de diálogo que contenga un CAPTCHA.

El valor devuelto por el método verifyWithRecaptcha() es un objeto Task. Al asociarle un manejador de evento on-success podrás adquirir un objeto RecaptchaTokenResponse, que contiene un token que puedes usar para saber si el usuario pasó o falló el CAPTCHA. A continuación aparece la forma de hacerlo:

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. Validando tokens CAPTCHA

El token que obtuviste en el paso anterior debe enviarse de nuevo al servicio reCAPTCHA para verificar si el usuario pasó o falló la prueba. Sin embargo, esta vez la llamada al servicio reCAPTCHA debe llevarse a cabo desde tu servidor back-end. 

Desde luego, el servidor no tendrá el token a menos que tu aplicación Android se lo envíe. Por lo tanto ahora debemos escribir código para enviar tokens desde la aplicación Android al servidor.

Por ahora vamos a asumir que nuestro servidor tiene un punto final llamado validate, que puede aceptar el token como un parámetro de cadena de consulta. Usaré el valor 10.0.2.2 como dirección IP del servidor y 8000 como su puerto. Si intentas ejecutar el servidor en tu propia computadora y la aplicación en un emulador que se esté ejecutando en el mismo equipo, tú también puedes usar la misma dirección IP.

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

Ahora puedes invocar al método httpGet() ofrecido por la biblioteca Fuel para enviar el token al servidor. El método espera una lista de parámetros de cadena de consulta como único argumento, así que te sugiero que uses el método de utilidad listOf() para crear una lista que contenga un único elemento: el token asignado a un parámetro de tipo consulta llamado user_token.

Ya que el método httpGet() se ejecuta de forma asíncrona, debes invocar al método responseString() para gestionar el valor que devuelve. El siguiente código te muestra cómo hacerlo:

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

4
    }

Puedes ver que ahora tenemos acceso a un objeto result. En caso de que no haya errores, éste contendrá la respuesta de nuestro servidor como una cadena.

Supongamos que nuestro servidor devuelve la cadena "PASS" si el usuario pasa la prueba, y "FAIL" de lo contrario. Desde luego, lo que en realidad tienes que hacer cuando el usuario pase o falle la prueba depende de tí. Por ahora te sugiero que simplemente muestres los mensajes Toast apropiados. El siguiente código te muestra cómo hacerlo de forma concisa:

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
})

En este punto la aplicación está lista. Puedes ir y desplegarla en tu emulador o dispositivo.

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

5. Creando el servidor

Hicimos muchas suposiciones acerca de nuestro servidor web en pasos anteriores. Ahora es momento de crearlo asegurándonos de que no difiera de esas suposiciones.

Una manera rápida y sencilla de crear un servidor web totalmente funcional es usar la plataforma Node.js y el framework Express.js. Para crear un nuevo proyecto de Node.js, crea un nuevo directorio en tu computadora y ejecuta el comando npm init dentro de él.

1
mkdir my_web_server
2
cd my_web_server ; npm init -y

Para añadir el framework Express al proyecto puedes usar el comando npm install.

1
npm install --save express

Además, necesitaremos el paquete Request para comunicarnos con el servicio reCAPTCHA. Por lo tanto instálalo como otra dependencia.

1
npm install --save request

Ahora puedes usar tu editor de código favorito para crear un nuevo archivo llamado index.js y comenzar a escribir todo el código del lado del servidor que sea necesario.

Comienza cargando los módulos express y request usando la función require() y creando una nueva aplicación Express al ejecutar la función express().

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

Nuestra aplicación Express debe tener un punto final llamado validate, al que se puede acceder usando el método HTTP GET. Por lo tanto crea una nueva ruta al mismo usando el método get():

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

3
});

Para validar el token generado por la aplicación Android, ahora debes crear una solicitud POST al servicio reCAPTCHA. La solicitud debe contener tu clave secreta y el token en sí. El siguiente código te muestra cómo construir el cuerpo de la solicitud POST extrayendo el token de la cadena de consulta:

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

Para llevar a cabo realmente la solicitud POST, puedes invocar al método post() del módulo request. Su respuesta es un pequeño documento JSON que contiene una clave llamada success. Como es de esperarse, su valor es true (verdadero) solamente si el usuario ha pasado la prueba.

El siguiente código te muestra cómo analizar el documento JSON, extraer la clave success y generar las respuestas "PASS" y "FAIL" que nuestra aplicación Android necesita:

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
});

Por último debes invocar al método listen() del objeto de la aplicación Express para permitir que éste escuche para buscar conexiones.

1
myApp.listen(8000);

En este punto nuestro servidor web está listo. Para arrancarlo regresa a la terminal y ejecuta el siguiente comando.

1
node index.js

Si ejecutas tu aplicación Android ahora, presionas el botón y resuelves un CAPTCHA de forma exitosa, deberás ver un mensaje Toast diciéndote que eres humano.

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

Conclusión

Ahora sabes cómo usar la API reCAPTCHA de SafetyNet para garantizar la seguridad de tu aplicación Android y tu infraestructura back-end contra bots.Ya no tienes qué preocuparte por registros automáticos, screen scrapers o spam generado por bots.

Para obtener más información sobre la API reCAPTCHA puedes consultar la documentación oficial.

Mientras tanto, ¡revisa otras de nuestras excelentes publicaciones sobre desarrollo de aplicaciones 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.