Sistema de Captcha en PHP

Buenas!

Hoy he decidido compartir con ustedes un sistema de captcha hecho íntegramente POR MI en PHP. Para los que no lo saben, los captchas, (acrónimo de "Completely Automated Public Turing test to tell Computers and Humans Apart", en español, "Prueba de Turing pública y automática para diferenciar máquinas y humanos" ), son textos aleatorios que se muestran dentro de una imagen y se pide al usuario que ingrese en un campo de formulario el texto mostrado. Si al enviar el formulario los textos coinciden, se realiza la acción correspondiente. Caso contrario se muestra un error o no se hace nada, lo que quieran. Para más información, hagan CLICK AQUÍ.

Sistema de Captcha en PHP


A la hora de hacer un sistema de captcha tienen varias alternativas:

1. Crean cada una de sus imágenes en algún editor, (photoshop, corel, fireworks, paint, el que quieran), y guardan todas las imágenes en una carpeta en su servidor.
2. Crean una imagen de fondo para sus captchas y hacen que las imágenes se generen solas tomando los textos de un archivo almacenado en su servidor.
3. Crean una imagen de fondo para sus captchas y hacen que las imágenes se generen solas tomando los textos de una base de datos cualquiera.

En mi caso, voy a trabajar con la opción 3. Ahora bien, como trabaja este sistema? Simple. En una base de datos MySQL tengo guardados todos los posibles textos que van a aparecer en mis captchas. Desde un script de PHP tomo un texto seleccionado al azar, creo una imagen PNG a partir de una imagen de fondo, le agrego el texto y la muestro en pantalla en un formulario.

Luego le pido al usuario que ingrese el texto mostrado en la imagen antes de enviar el formulario. Una vez que el formulario es enviado, verifico que los textos coincidan. Si lo hacen significa que puedo realizar la acción que tenía que hacer el formulario, (agregar un nuevo registro a una base de datos, modificar, eliminar, etc). Caso contrario significa que es un BOT tratando de hacer algo en mi página o que el usuario no sabe copiar un texto.

PHP

Empecemos con el diseño.

1- Lo primero que tenemos que hacer es tener una tabla en una base de datos donde voy a guardar los posibles textos de mis captchas. Calculo que tienen idea de como crear una base de datos, tablas y demás así que sólo voy a hablar de la estructura. La base de datos se llama "principal". Adentro tiene una tabla que se llama "textoscaptcha" y tiene sólo 2 campos: "id" y "texto". El campo "id" es el índice de la tabla. Único, numérico y auto-incrementable, (esto significa que es un número que sólo existe una vez dentro de esa tabla por lo tanto cada fila tiene un id único).
O sea, algo como esto:

script


sistema

2- Una vez que tenemos nuestra tabla modelada y lista vamos a necesitar una imagen de fondo para nuestro captcha. La pueden hacer en cualquier programa que quieran y en el tamaño que más les guste. El único requisito es que TIENE QUE SER PNG! Sino no va a andar. Les dejo una recopilación de fondos para captcha que encontré dando vueltas por internet:
fuente


La idea es que nos quede algo así:

MySQL


Por comodidad, vamos a crear en el escritorio una carpeta nueva con el nombre de "sistemaCaptcha" y vamos a poner nuestro fondo dentro de esa carpeta. Al fondo lo vamos a llamar "fondo.png".

Por último, la ventaja de este script es que les va a permitir IMPORTAR CUALQUIER FUENTE QUE QUIERAN PARA USARLA COMO FUENTE DEL TEXTO DE SU IMÁGEN! Para esto vamos a necesitar una fuente del tipo TrueType, (pueden descargar un montón desde AQUÍ). Vamos a descargar la que más nos guste y la vamos a guardar en la carpeta "sistemaCaptcha" que creamos antes con el nombre de "fuenteCaptcha". La extensión de las fuentes es "ttf".

Ya tenemos todo listo para empezar a trabajar con PHP!

png

3- La programación: Dentro de la carpeta "sistemaCaptcha" vamos a crear un nuevo archivo PHP llamado "captcha.php", (usen el Dreamweaver, Bloc de notas, su preferido). Este archivo es el encargado de tomar la palabra de la base de datos y armar la imagen con ella. El archivo va a tener lo siguiente:

<?PHP
// Me conecto con la base de datos. Ustedes cambien estos valores por los suyos.
$conexion mysql_connect("localhost""root""" );
mysql_select_db("test"$conexion);
// Abro una nueva sesión.
session_start();
/*
Selecciono uno de todos los id's posibles de la tabla "textoscaptcha" usando la función
"rand(minimo, máximo)" de PHP. El resultado es que en la variable $idTexto se termina
almacenando uno de todos los id's almacenados en la tabla.
*/
$idTexto rand(1mysql_num_rows(mysql_query("SELECT id FROM textoscaptcha" ))) ;
// Consulto el texto que tiene ese id y lo guardo en la variable "$textoImagen".
$consulta mysql_query("SELECT texto FROM textoscaptcha WHERE id='$idTexto'" ) ;
$textoImagen mysql_fetch_array($consulta) ;
$textoImagen $textoImagen['texto'];
/*
Este es un punto MUY importante. Guardo en una variable de sesión el valor correcto
del captcha. Contra este valor voy a comparar cuando el usuario escriba el texto
mostrado en la imagen.
*/
$_SESSION['controlCaptcha'] = md5(strtoupper($textoImagen)) ;
// Creo la nueva imágen a partir del archivo "fondo.png" que tenemos en la carpeta.
$captcha imagecreatefrompng("fondo.png" ) ;
/*
Le agrego el texto a la imagen. Esta función trabaja con los siguientes parámetros:

imagettftext(imagen, tamañoFuente, anguloTexto, posX, posY, color, fuente, texto)
*/
imagettftext($captcha15030250"fuenteCaptcha.ttf"$textoImagen);
// Genero la imágen PNG y listo!
header("Content-type: image/png" ) ; 
imagepng($captcha) ;
?>

Con esto ya tenemos andando el archivo "captcha.php". Si lo ejecutan van a ver como aparece la imagen PNG con su fuente, tamaño de texto, imagen de fondo y la variable de control creada.

true type

Ahora, para implementar todo esto en un formulario tenemos que hacer lo siguiente. Vamos a armar un formulario básico que pida sólo el texto en el catpcha. Ustedes agreguen sus variables y tratenlas como quieran en el archivo. Veamos como se relacionan. Vamos a crear un archivo "index.php" que va a tener sólo un formulario, la imagen del captcha, un cuadro de texto y un botón para enviar el formulario. Por ejemplo:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Mi primer captcha</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="resultados.php">
<p align="center"><img src="captcha.php" width="300" height="30" border="1" /></p>
<p align="center">Texto:
<input type="text" name="textoCaptcha" />
</p>
<p align="center">
<input type="submit" name="Submit" value="Ingresar" />
</p>
</form>
</body>
</html>

Fijense la parte que está en negrita! Lo que hace acá es poner como URL de la imagen el archivo PHP. ¿Por que hace esto? Porque nuestro archivo PHP genera una imagen PNG mediante sus headers por lo tanto al ejecutarse el resultado es una imagen.

Con ese código, deberían tener algo como esto:

captcha


Si prestan atención, van a ver que action del formulario lleva a la página "resultados.php". Esta es la página de validar que el texto ingresado sea el mismo que el de la imagen. Vamos a crear un archivo php y lo vamos a guardar en nuestra carpeta con el nombre "resultados.php". Adentro va a tener sólo esto:

<?PHP
// inicio la sesión
session_start();
/*
Recibo la variable que ingresó el usuario y la encripto para compararla con la que está
almacenada en la sesión.
*/
$textoCaptcha md5(strtoupper($_POST['textoCaptcha']));
// Comparo las dos variables.
if($textoCaptcha != $_SESSION['controlCaptcha'])
{
/*
Si son distintas significa que el texto ingresado es distinto al de la imagen. Vuelvo al
index y muestro un error.
*/
header("Location: index.php?error=1" );
exit();
}else{
// Son iguales. Acá realizo todas las acciones que quiera!
echo "Es el mismo texto  ^^  ";
}
?>

imagenes

Y eso sería todo! Ya tienen su sistema de captcha programado y andando!!!

Pueden pulirlo muchísimo más:
- Hacer que los textos salgan centrados en la imagen.
- Validar que la ID seleccionada exista realmente en la base de datos.
- Validar la forma de ingreso al archivo "resultados.php".
- Mostrar el error en el archivo "index.php" cuando el texto no sea correcto
- Etc...

Pero bueno, eso ya es tarea para cada uno! Espero que a alguien le sirva y espero sus comentarios!

Un abrazo!

Fuentes de Información - Sistema de Captcha en PHP

Dar puntos
95 Puntos
Votos: 11 - T!score: 9/10
  • 2 Seguidores
  • 5.420 Visitas
  • 28 Favoritos

23 comentarios - Sistema de Captcha en PHP

@trescirculos Hace más de 4 años
Justo yo estoy por hacer un videotutorial, la idea es aplicarle otras tecnicas mas, pero muy buen post te felicito!. Si tenes ganas sumate a la comunidad de diseño web.

+10

Saludos!
@Kriis_bkn_1990 Hace más de 4 años
muy bueno +10
@pc_fan_04 Hace más de 4 años
Gracias me re sirve acuerdame de los 10
@Chapullin87 Hace más de 4 años
Gracias man!!! Soy medio newbie con PHP... gracias por el empujon.. si tuviese puntos te los dejaria...
Salutte
@Amazona_ Hace más de 4 años
Con esta clase de posts sos novato??? no puede ser che! ...te sigo de una! y mañana te ayudo con puntines!
@bebotinia Hace más de 4 años
+10 para q seas new full user
@elsuspendidoII Hace más de 4 años -1
Captchas
-------------------------------------------------------------------------------------------
Yo te sigo igual el aprendizaje siempre es bienvenido
@tyncho86 Hace más de 4 años -1
Muy bueno! Van otros 10 para que seas NFU
@trescirculos Hace más de 4 años +1
Amazona_ dijo:Con esta clase de posts sos novato??? no puede ser che! ...te sigo de una! y mañana te ayudo con puntines!


Idem!!

Bienvenido NFU!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@ivank77 Hace más de 4 años -1
maldito fede ya sos NFU ¬¬ me ganaste jajjaaj! bonito post! &quot; re post&quot; jjajano mentira! felicitaciones!
@driconmax Hace más de 4 años
Muy bueno
@arucordoba Hace más de 4 años
+10
@8MoCoSo7 Hace más de 4 años

&lt;?php
echo '&lt;font face=&quot;Arial&quot; color=&quot;#c2c2c2&quot; size=&quot;3&quot;&gt;Queda re copado si, l&amp;aacute;stima que no ejecuta ^_^&lt;/font&gt;;
?&gt;

@alexjusa Hace más de 3 años
&lt;?php
echo '&lt;font face=&quot;Arial&quot; color=&quot;#c2c2c2&quot; size=&quot;3&quot;&gt;Queda re copado si, l&amp;aacute;stima que no ejecuta ^_^&lt;/font&gt;;
?&gt;
@esteban22x Hace más de 3 años
ok ..pregunto.
Es posible hacer un sistema de captcha en javascript?
Mi segunda pregunta.
Se podria realizar con numeros y letras aleatorios y compilarlos al entrar a la base de datos en SHA-1 ?
@d3m3n70R Hace más de 3 años
esteban22x dijo:ok ..pregunto.
Es posible hacer un sistema de captcha en javascript?
Mi segunda pregunta.
Se podria realizar con numeros y letras aleatorios y compilarlos al entrar a la base de datos en SHA-1 ?

Si es posible le hice una mejora y lo postee gracias por tu inspiracion para crear mi deseño
@txalito Hace más de 3 años
Hola. Puede ser que no se vean las imagenes del post?
@el_nata_12 Hace más de 2 años
+3