Imagen de validación de formularios con PHP
Introducción
Actualmente, cuando una web desea obtener datos de un usuario le
proporciona un formulario que debe rellenar con la información
que se desea recoger y que serán guardados (normalmente) en
una base de datos.
Esto se hace para evitar evitar que programas automatizados
rellenen las bases de datos que recogen esta información de basura.
Para este gran problema, actualmente se opta por enviar una
imagen aleatoria (que contiene un texto
alfanumérico) junto con el formulario. De manera que cuando
el
usuario desee enviar los datos, deba indicar que texto es el que se
muestra en la imágen.
(Estos programas automatizados, normalmente no son capaces de detectar
que texto se muestra en la imagen, por lo que nuestra web
estará
libre de su ataque malicioso).
El motivo de este tutorial es
intentar utilizar otra técnica
que la que se ven en otros tutoriales que hay en el Web. Desde mi punto
de vista la técnica que se muestra en estos tutoriales es
mejorable, pues lo que hacen es generar una imagen aleatoria y
guardarla en el disco duro del servidor y permanece hay mientras el
usuario no envie el texto de validación correcto… Esto
hace
que el servidor se llene de miles de imágenes y sea
costosisimo
luego de eliminar a mano. (Por supuesto siempre se puede hacer un
script que las borre automáticamente utilizando
algún
criterio. Por ejemplo, que borre aquellas imágenes que
lleven
más de una hora en el disco duro.
Nosotros lo vamos hacer igual, pero sin guardar ninguna imagen en el disco duro del servidor.. más que nada por que
creo que no hace falta hacerlo para llegar al fin deseado.
Vamos a ver un Ejemplo
Este es el Script al que accede el usuario y que envia el
formulario
que tiene que rellenar el usuario. El script es autocomentado (Todo el
código fuente debería serlo) .
<?php /* @author. Carlos García Pérez. Autentia Real Business Solutions Este Script inicia la sesión si no estaba iniciada ya y envia el formulario a rellenar al usuario */ // Iniciamos la sesión session_start(); if (! isset($_SESSION["imageText"])){ // No estaba creada la sesión, la creamos. // Generamos una cadena aleatoria que será la se envie como imagen al usuario. $_SESSION["imageText"] = generateRandString(4); session_write_close(); } /** * Genera una cadena aleatoria de 'numChars' caracteres. */ function generateRandString($numChars){ // Quitamos los caracteres {0, 1, i, l, o) pues confunden // mucho a los usuarios ya que por ejemplo un cero y una o se ven más o menos // igual. $chars = "AaBbCcDdEeFfGgHhJjKkMmNnPpQqRrSsTtUuVvWwXxYyZx23456789"; $charsCount = strlen($chars) - 1; $randString = ""; for ($i=0; $i < $numChars; $i++){ $num = rand(0, $charsCount); $randString .= $chars[$num]; } return $randString; } ?>Autentia Real Business Solutions
Este es el Script getImage.php
genera la imagen asociada a la variable almacenada en sesión.
<?php /* @author. Carlos García Pérez. @company. Autentia Real Business Solutions Este script genera la imagen de validación del formulario */ session_start(); $imageText = $_SESSION["imageText"]; // Verificamos que el usuario inicio sesión if (! isset($imageText)){ // El usuario no inicio sessión header("HTTP/1.0 405"); // Recurso no permitido return; } // Constantes que nos harán el código más legible define("HEIGHT", 30); define("SPC", 20); define("WIDTH", (SPC * strlen($imageText))); define("FONTNAME", "ARIAL.TTF"); define("FONTSIZE", 18); /* { Generamos la imagen. } * Nota: * Esta parte podría ser cambiada para generar una imagen más compleja de * averiguar por programas de detección de imágenes. */ $img = @imagecreate(WIDTH, HEIGHT); @imagecolorallocate($img, 200, 200, 200); $black = @imagecolorallocate($img, 0, 0, 0); @imagerectangle($img, 0, 0, WIDTH - 1, HEIGHT - 1, $black); for ($i=0, $l = strlen($imageText); $i < $l; $i++){ @imagettftext($img, FONTSIZE, 10, $i*SPC + 2, 26, $black, FONTNAME, $imageText[$i]); } // Fin { Generamos la imagen } // Enviamos la imagen al cliente (Navegador, PDA, Móvil, etc). // Como veis no se guarda nada en el disco duro pues le enviamos la imagen directamente al cliente. @imagepng($img); // Liberamos recursos @imagedestroy($img); ?>
El siguiente script processCommentForm.php
es el que recibe los datos que se envian desde el formulario.
<?php /* @author. Carlos García Pérez. @company. Autentia Real Business Solutions Este script valida que el texto introducido por el usuario y si es igual al que estaba guardado en sesión almacenamos los datos en nuestra BD. */ session_start(); $imageText = $_SESSION["imageText"]; // Verificamos que el usuario inicio sesión if (! isset($imageText)){ // El usuario no inicio sesión header("HTTP/1.0 405"); // Recurso no permitido return; } $resultText = ""; // Comprobamos (case-sensitive) que el texto que introdujo el usuario // es igual al que estaba guardado en sesión. if ($imageText == $_POST["txtRandImage"]){ // El usuario introdujo correctamente el valor de la imágen // Destruimos todas las variables de la sesión y la sesión en si misma. session_unset(); session_destroy(); // Aquí procesariamos y guardariamos los datos del formulario (vienen en $_POST) en nuestras BD o ficheros. (En este ejemplo no lo hacemos). $resultText = "Validación correcta. Sus comentarios fueron guardados"; } else { $resultText = "Validación incorrecta. Inténtelo de nuevo"; } // En este ejemplo simplemente se envia un mensaje al usuario. echo $resultText; ?>
Bueno, espero que os haya sido de utilidad este tutorial.
En Autentia,
empresa en la cual trabajo, nos gusta compartir el conocimiento. Aquí teneis un
poquito más de nuestra aportación. Si
algún día necesitais un poco de ayuda con vuestros proyectos o
necesitais de formación ya sabéis donde
encontrarnos.