Cómo hacer un captcha en PHP

En este artículo vamos a explicar cómo hacer un CAPTCHA en PHP para proteger nuestros formularios de robots spam.

Literalmente un CAPTCHA es un acrónimo de «Completely Automated Public Turing test to tell Computers and Humans Apart» (Prueba de Turing pública completamente automatizada para diferenciar entre computadoras y humanos).

Se trata de un sistema de seguridad utilizado en línea para determinar si el usuario que está intentando acceder a un sitio web o realizar una acción en línea, es humano o un programa informático automatizado.

Tipos de captcha

Los CAPTCHA tradicionalmente consisten en una imagen o un conjunto de caracteres distorsionados y difíciles de leer que el usuario debe ingresar correctamente en un campo de texto para poder continuar. Los humanos pueden generalmente leer y transcribir el contenido del CAPTCHA, mientras que los programas informáticos automatizados tienen más dificultades para hacerlo.

Existen muchos tipos de CAPTCHA, algunos de ellos ofrecidos por servicios externos a nuestra web que podemos utilizar e implementar como los producidos por Google.

Tipo de captcha basado en recuadro de texto
Tipo de captcha basado en imágenes

Hacer un captcha con PHP

En este artículo vamos a explicar cómo hacer un CAPTCHA con PHP basado en un texto aleatorio sobre una imagen predefinida, de manera que sea difícil de leer para un robot de spam y fácil para un humano.

En un entorno web los CAPTCHA se utilizan comúnmente para prevenir el spam de robots automatizados que intentan insertar mensajes, así como ataques informáticos automatizados, sobretodo en formularios, logins, blogs, foros, etc.

El CAPTCHA que voy a explicar es el mismo que utilizo en mi web Gestor Ligas y tiene el siguiente aspecto:

Ejemplo de captcha con PHP
Ejemplo de Captcha

Se trata de un CAPTCHA fácilmente configurable a nivel de código y para que todo el proceso funcione hay que tener en cuenta 3 aspectos fundamentales:

  • Utilizaremos una imagen de fondo ya creada
  • Debemos tener activas las SESIONES en nuestra web
  • Debemos enlazar correctamente las fuentes TrueType

El código es el siguiente y debes guardarlo en un archivo independiente, por ejemplo captcha.php.

<?php
function randomText($length) {
	$text = '';
	$pattern = "abcdefghkmnpqrstuvwxyz123456789ABCDEFGHJKLMNPQRSTUVWXYZ";
	for($i=0; $i<$length; $i++) $text .= $pattern[rand(0, strlen($pattern)-1)];
	return $text;
}
$font = $_SERVER['DOCUMENT_ROOT'] . '/mi_dominio/fonts/comic.ttf';
$texto = randomText(6);
$_SESSION['captcha'] = $texto;
$captcha = imagecreatefromjpeg("imagenes/capbg.jpg");
$colText = imagecolorallocate($captcha, 0, 0, 0);
imagettftext($captcha, 16, 0, 10, 30, $colText, $font, $texto);
imagejpeg($captcha, NULL, 80);
imagedestroy($captcha);
header('Content-type: image/jpg');
// var_dump($_SESSION['captcha'], $font, $img);
?>

Explicación del código captcha

La explicación del código paso a paso es el siguiente:

  • Primero se define una función llamada randomText() que genera una cadena de texto aleatoria. La función recibe un parámetro $length que determina la longitud de la cadena generada. Se utiliza un patrón de caracteres para generar la cadena aleatoria. En este caso he quitado las letras (i) y (l) que suelen confundirse y la (ñ) que sólo existe en España.
  • Se define la variable $font, que almacena la ruta de la fuente TrueType utilizada para generar el texto en el CAPTCHA. Esta ruta debe ser del tipo $_SERVER[‘DOCUMENT_ROOT’] hasta el directorio donde tengas instalada la fuente TrueType en tu Hosting. Lo más probable es que debas instalar alguna fuente para poder acceder a ella sin problemas.
  • Se llama a la función randomText(6) para generar una cadena aleatoria de 6 caracteres y se almacena en la variable $texto. Si decides añadir más o menos caracteres deberás volver a jugar con el tamaño de la imagen y la posición del texto para que quede centrado. En mi caso utilizo una imagen de 100×40 píxels y 6 caracteres de tamaño 16.
  • El valor del CAPTCHA generado se almacena en la variable de sesión $_SESSION['captcha']. Recuerda que tu web ya debe tener la sesión activada con session_start().
  • Se crea una nueva imagen a partir de un archivo JPEG llamado capbg.jpg utilizando la función imagecreatefromjpeg() y la guardamos en la variable $captcha.
  • Se define el color del texto en el CAPTCHA utilizando la función imagecolorallocate() en formato RGB que en este caso será negro.
  • Se genera el texto sobre la imagen utilizando la función imagettftext() que es una función de la biblioteca GD de PHP utilizada para crear textos con fuentes TrueType. Los parámetros que utiliza esta instrucción son (image, size, angle, x, y, color, font, text). Con esto podemos le indicamos la imagen sobre la que dibujar, el tamaño del texto, ángulo del texto, posición (x, y) del texto sobre la imagen, color del texto, fuente TrueType y el texto a escribir.
  • Se exporta la imagen como un archivo JPEG utilizando la función imagejpeg(). Esta instrucción recibe la imagen creada en $captcha y opcionalmente una ruta de entrega (null) y la calidad del jpg que por defecto es 75.
  • Una vez tenemos la imagen exportada liberamos la memoria utilizada con imagedestroy().
  • Finalmente hacemos que todo el script se envíe como una imagen JPEG al navegador utilizando la función header().
  • Si algo falla puedes descomentar la linea var_dump() para mostrar los valores de $_SESSION['captcha'], $font, $img y los mensajes de error en el navegador.

Aplicar nuestro captcha PHP a un formulario

Para que todo funcione ahora debemos añadir nuestro CAPTCHA a los formularios donde queremos prevenir los ataques de robots spam como en la siguiente imagen:

Funcionamiento del captcha en un formulario
Captcha en un formulario

Este fragmento de formulario debes añadirlo a tu web y básicamente el código es el siguiente:

<label>&nbsp;</label>		
<div class="float-left">
    <img id="captcha" name="captcha" src="https://gestorligas.com/captcha.php" />&nbsp;
    <a href="javascript:newCaptcha()"><img src="https://gestorligas.com/imagenes/renew.png" /></a>
</div>

<div class="clearfix"></div>

<label>Código de seguridad:</label>		
<input id="Captcha" name="Captcha" type="text" required />
<p>(*) Introduce el código de seguridad de la imagen, pulsa renovar si no lo ves claramente</p>

<p class="text-right">
    <input class="btn-success" type="submit" name="submit" value="Enviar" />
</p>
<p class="text-left">(*) Campos obligatorios</p>		

Evidentemente tu web HTML tendrá otros estilos css y otras alineaciones, ahora lo interesante es ver cómo se implementa el CAPTCHA en el formulario HTML.

  • Mostramos la imagen del CAPTCHA llamando a nuestro script captcha.php
  • Opcionalmente podemos hacer una función para renovar el CAPTCHA enlazando a una función JavaScript que vuelve a cargar la imagen.
  • Creamos un <input> para que el usuario introduzca el texto que visualiza en nuestro CAPTCHA

Verificar el captcha

Una vez que el usuario rellena todo el formulario y lo envía sólo falta recibir los datos y comprobar que el CAPTCHA es correcto, evitando ataques de robots spam.

Para ello obtenemos los campos del formulario y comprobamos que el texto introducido por el usuario coincida con el texto de nuestra imagen CAPTCHA que se ha guardado en la sesión. Si hay un error debemos asumir que es un error del usuario o un robot spam, si es correcto podemos seguir con la validación del formulario.

<?php
if ($_POST['Captcha'] <> $_SESSION['captcha'] 'ERROR, código de seguridad incorrecto ...';
else validar_form();
?>

Todo esto es un ejemplo de cómo implemento mi propio CAPTCHA en mis webs. En tu web deberás adaptarlo a tus necesidades igual que yo lo tengo adaptado a las mías, añadir filtros de seguridad, mensajes de error, etc.

¡ Espero que este artículo sea de vuestro interés !

Deja un comentario