Creando un formulario con CAPTCHA en PHP

Veremos como implementar un captcha para nuestro formulario usando PHP y AJAX.

Rodríguez Patiño, Eduardo
2020-10-01 | 20,660 lecturas

Bien muchachos hemos creado esta nueva entrada usando la arquitectura MVC para agilizar el desarrollo de nuestro proyecto y Bootstrap para la rápida maquetación.

En nuestro ejemplo hemos creado un simple formulario de comentario que requiere la validación del CAPTCHA para procesar los datos.

Nuestro formulario
Vamos a ver el formulario que hemos maquetado usando Boostrap 3, lo que más nos interesa es la etiqueta form y la de imagen. Ya que con la primera vamos a procesar la información para validar el captcha, y la imagen la vamos a usar para mostrar el captcha.

<h1 class="page-header text-center">¡Ejemplo de formulario con Captcha!</h1>

<div class="row">
    <div class="col-xs-2"></div>
    <div class="col-xs-8">
        <fieldset>
            <legend class="text-center">Ingrese su comentario</legend>

            <form id="frm-comentar" action="?c=Home&a=Procesar" method="post">
                <div class="form-group">
                    <label>Nombre</label>
                    <input type="text" class="form-control" name="Nombre"  data-validacion-tipo="requerido|min:3" />
                </div>
                <div class="form-group">
                    <label>Comentario</label>
                    <textarea class="form-control" name="Comentario"  data-validacion-tipo="requerido|min:10"></textarea>
                </div>
                <div class="form-group">
                    <label>Captcha</label>
                    <input type="text" name="Captcha" class="form-control" data-validacion-tipo="requerido|min:5" maxlength="5" />
                </div>
                <div class="thumbnail">
                    <img id="captcha" src="" />
                </div>
                <button class="btn btn-info btn-lg btn-block" type="submit">Enviar</button>                
            </form>
        </fieldset>
    </div>
</div>

La clase Captcha
En la jerarquía de nuestra carpeta tenemos una llamada lib, ahí hemos creado la clase Captcha, la cual contiene 2 métodos:

  • Mostrar(), la cual se encarga de crear el captcha. El truco es crear un texto al azar de 5 caracteres como máximo para guardarlo en sesion y nuestro siguiente método lo pueda validar.

  • Valida($valor), la cual se encarga de comparar un valor que se le pase al método con el valor valor que guardo en sesion nuestro método Mostrar();

  • Para la fuente hemos descargado una del tipo TrueType (ttf). Parece que la que he usado para el ejemplo es un poco complicado de leer, bueno puedes usar otra buscando en google "ttf fonts".

Image title

Image title


Mostrando al captcha en forma de imagen
Luego hemos creado un controlador que le hemos puesto de nombre CaptchaController, el cual usaremos como ruta para mostrar el captcha en nuestra etiqueta

El captcha lo cargamos mediante javascript, ya que si nuestro formulario falla volvemos a recrear el captcha.

function CargaCaptcha()
{
    var d = new Date();
    $("#captcha").attr('src', '?c=Captcha&' + d.getTime());
}

Como se darán cuenta usamos un getTime() para tener un nuevo valor cada ves que se llame al método CargaCaptcha(), ya que de esta manera podemos crear la misma imagen N veces, del caso contrario no refrescaría la imagen.

El código completo es el siguiente:

$(document).ready(function(){
    // Cargamos el captcha
    CargaCaptcha();

    $("#frm-comentar").submit(function(){

        var obj = $(this);

        if(obj.validate()) {
           $.post(obj.attr('action'), obj.serialize(), function(r)
           {
                // En caso de que el captcha no sea correcto, volvemos a cargar
                if(!r.respuesta) 
                {
                    CargaCaptcha();
                }
                else 
                {
                    obj.html('<div class="alert alert-info text-center">¡Su comentario ha sido enviado con éxito!</div>');
                }

           }, 'json')                
        }

        return false;
    });
})

Como pueden ver usamos la propiedad $.post para mandar los datos mediante ajax. La propiedad $.serialize() se encarga de recoger todo los valores del formulario tomando como key el nombre del campo y como value el valor del campo, de esta manera nos evitamos hacer este trabajo un por uno.

Validando el captcha
Nuestro formulario apunta a una dirección, esta en teoría debe contener todo el código para enviar el comentario. Pero yo solo he puesto el código para validar el captcha el cual es el siguiente:

Image title