Imagen de validación de formularios con PHP

0
17473

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;
  }
  ?>
Comentarios:

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.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad