Cómo crear captcha con PHP y Ajax código fuente

CAPTCHA en PHP AJAX y HTM5 canvas

CAPTCHA significado en español Prueba de Turing completamente automática y pública para diferenciar ordenadores de humanos, se utilizo por primera vez en una aplicación web en el año 2000, para la medida de seguridad en los formularios de envió al servidor, un ejemplo claro en un sistema de login , formularios de registro y demás.

En los siguientes párrafos aprenderemos  cómo crear CAPTCHA con PHP y Ajax, esto para protegernos  de los robots malintencionadas que puedan acceder a la paginas privadas y por los envíos automáticos masivos, y no solamente de robots, ya que también existen ciertas personas con malas intenciones de hacer daño, como por ejemplo con un programa de petición HTTP automática masivo hacia los servidores. En los ejemplos crearemos dos maneras diferentes de CAPTCHAs: el primero sera generar claves y mostrar en una imagen distorsionada, segundo sera mostrar al usuario que realice una operación matemática y también existen otras diferentes maneras de crear, eso ya lo vera usted o simplemente idearse otro diferente.

CATPCHA generando claves aleatorias números y letras.

CAPTCHA en PHP AJAX y HTM5 canvas

Se crea un formulario  de login incompleto, que agrupa un campo de texto y etiqueta canvas que  esta disponible en HTML5 que nos permitirá dibujar las claves en Javascript mediante AJAX.

Archivo:index1.php

<?php
/**
 * Formulario de login incompleto
 * Para CAPTCHA
 * Autor: Rodrigo Chambi Q.
 * Mail:  filvovmax@gmail.com
 * web:   www.gitmedio.com
 */
?>
<!DOCTYPE html>
		<html>
		<head>
			<title>Captcha</title>
			<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
			<!-- vinculo a bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Temas-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="estilo.css">
		</head>
		<body>
		 <div id="Contenedor">
		 <div class="Icon"><span class="glyphicon glyphicon-user"></span></div>
		 <div class="ContentForm">
		 	<form action="" method="post" name="FormEntrar">
                <div class="input-group input-group-lg">
				 <span class="input-group-addon" id="sizing-addon1" style="padding-right:4px; padding-left:4px;"> <button style="margin-left: 0px;" type="button" class="btn btn-default btncapt"><i class="glyphicon glyphicon-refresh"></i></button> </span>
                      <!--<img src="capt.php" class="imct">-->
                    <!--Etiqueta canvas para dibujar clave-->
				   <canvas id="capatcha"  style="width:100%;  border: 1px solid #ccc; float:left;  " height="62"></canvas>
				</div>
				<br>
				 <div class="input-group input-group-lg">
				 <span  class="input-group-addon" id="sizing-addon1" ><i class="glyphicon glyphicon-asterisk"></i></span>
				      <!--Caja de texto que permite introducir las claves-->
                      <input type="text" name="contra" id="valorCapt" class="form-control" placeholder="" aria-describedby="sizing-addon1" required>
				</div>
				<br>
				<button class="btn btn-lg btn-primary btn-block btn-signin" id="IngresoLog" type="button">Entrar</button>
				<!--<div class="opcioncontra"><a href="">Olvidaste tu contraseña?</a></div>-->
		 	</form>
		 </div>	
		 </div>
		</body>
		<!-- vinculando a libreria Jquery-->
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
		<!-- Libreria java scritp de bootstrap -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script type="text/javascript" src="jsScript.js"></script>
		</html>

En el siguiente ejemplo de código muestra como hacer petición AJAX al servidor, y dibujar la clave  devuelto del servidor.

Archivo;validator.js

$( document ).ready(function() {
    $("#IngresoLog").click(function(event) {
      //event.preventDefault();
      //Se envia peticion Ajax
      //al servidor para verificar
      //si la clave intrdocida es la
      //correcta, y nos nuestra en un alert
      $.ajax({
        url: 'VerifCaptha.php',
        type: 'POST',
        dataType: 'text',
        data: {"valor": $("#valorCapt").val()},
      })
      .done(function(data) {
       alert(data);
      })
      .fail(function() {
        //console.log("error");
      })
      .always(function() {
        //console.log("complete");
      });
      
      });
//Reccarga al hacer clik en el 
//boton par generar nuevo clave
 $(".btncapt").click(function(event) {
    CargarCaptcha();
 });

 CargarCaptcha();
});

/**
 * Realiza la peticion AJAX
 * al servidor para generar clave
 */
function CargarCaptcha() {
   $.ajax({
    url: 'captcha2.php',
    type: 'post',
    dataType: 'text',
    data:{"capt":"visto"}
   })
   .done(function(data) {
   // alert(data);
    var visto=$.parseJSON(data);
    //Dibujamos en el CANVA las claves 
    //devueltas por el servidor
    var canva=document.getElementById("capatcha");
    var dibujar=canva.getContext("2d");
    canva.width = canva.width;
    dibujar.fillStyle="red";
    dibujar.font='20pt "NeoPrint M319"';
    dibujar.fillText(visto.retornar,6,39);
    //console.log(data);
   })
   .fail(function() {
    //console.log("error");
   })
   .always(function() {
    //console.log("complete");
   });
}  

A continuación script PHP para generar claves aleatorias, se usa la librería PasswordLib.php para incriptar las claves generadas para el contenido de la cookie. El método GenerarCaptcha($cant) permite generar la longitud de claves de forma aleatoria, en el cual se usa el método rand de PHP.

Archivo:captcha2.php

<?php 
/**
 * Autor: Rodrigo Chambi Q.
 * Mail:  filvovmax@gmail.com
 * web:   www.gitmedio.com
 * Generador de clave, para CAPTCHA
 */
//Importando la libreria para incriptar
require_once 'classphp/PasswordLib/PasswordLib.php';
//Metodo generador de claves CAPTCHA
function GenerarCaptcha($cantidad){
	$captcha=null;
	//Arreglo para que genere caracteres
	//numericos y letras
	$carater=array(
	1,2,3,4,5,6,7,8,9,0,
	'a','b','c','d','e','f','g','h','i','j',
	'k','l','m','o','p','q','r','s','t','v',
	'w','x','y','z','A','B','C','D','F','G',
	'H','I','J','K','L','M','N','O','P','K',
	'R','S','T','V','W','X','Y','Z');
	//Se realiza la generacion
	//de cantidad de caracters
	$posicion=0;
	while ($posicion<=($cantidad-1)) {  
	     $radom=rand(0,count($carater)-1);
	     $captcha .=$carater[$radom];
	     $posicion++;
	}
 return $captcha;
}
//Determinamos el envio de datos por parte del usuario
if(!empty($_POST['capt'])){
         //si usuario envía datos correctamente
         //se genera datos aleatorios
         //guardando a ala variable global
	$_SESSION["valor"]=rand(0,50);
}
if(!empty($_SESSION["valor"])){
         //Se verifica la variable global
         //si contiene datos,se generara las claves 
	if(strlen($_SESSION["valor"])>0){
        $captcha=GenerarCaptcha(6);
	//instnacia de la clase para incriptar el
	//contendino del cookie
        $PasswordLib = new \PasswordLib\PasswordLib;
        $hash = $PasswordLib->createPasswordHash($captcha);
        //Enviamos enformacion para que se almacen 
        //en el navegador del usaurio
	setcookie('captcha',$hash,time()+60*3);
	//Imprime en  el formato JSON 
	//para mostrar la claves generadas al
	//usuario
	if($captcha!=""){
		echo '{"retornar":"'.$captcha.'"}';
	}else{
		echo '{"retornar":false}';
	} 
	}
  }
     
 ?>

En el siguiente script php, se determina o valida cuando el usuario ingresa las claves en el formulario.

Archivo:VerifCaptha.php

<?php 
session_start();
require_once 'classphp/PasswordLib/PasswordLib.php';
//Verificamos la entrada de variable global
if(!empty($_POST['valor'])){
 $PasswordLib = new PasswordLib\PasswordLib();
 // Verificamos la clave incriptada en el contenido de la cookie
 $boolean = $PasswordLib->verifyPasswordHash($_POST['valor'],$_COOKIE["captcha"]);
 //Se imprime el mesaje
 if($boolean==true){
 echo "Captcha Correcta";
 }else{
 echo "Captcha Incorrecta";
 }
}
 ?>

CATPCHA con operación matemática.

CAPTCHA con operacion matematica PHP AJAX CANVAS

Ya hemos visto en los anteriores ejemplos de código como hacer el formulario, realizar petición al servidor con AJAX y validar la clave cuando el usuario ingresa cuyo clave, por el cual se usa los mismos códigos, excepto en el siguiente ejemplo de código se mostrara como generar CAPTCHA con operación matemática, existen dos métodos el primero llamado: NumerAletorios(), este método se encarga de generar  números y operadores aritméticos aleatorios, el segundo método Operacion($string), se encarga  de realizar las operaciones matemáticas. Tal como se ve en el siguiente ejemplo.

Archivo:captcha1.php

<?php
session_start();
require_once 'classphp/PasswordLib/PasswordLib.php';
/**
 * Genera Numeros Aleatorios
 * y con uno de las operaciones
 * aritméticas
 */
function NumerAletorios(){
  $operacion =array('+','-',
  	               '*','/');
  $mostrar   =null;
  $num1      =rand(0,50);
  $num2      =rand(0,20);
  $op        =rand(0,count($operacion)-1);
  $optiom    =$operacion[$op];
  $mostrar   =$num1.$optiom.$num2;
  return $mostrar;
}

/**
 * Parsea para la operación
 * aritmética.
 * @param string $string [string con la operación aritmética]
 */
function Operacion($string){
	$resutado=0;
	//Operadores aritméticos
    $valor=array('+','-',
  	         '*','/');
	foreach ($valor as $key => $value) {
		//Realizamos la búsqueda de dígitos y operadores
		//con método preg_match, al cumplirse realiza la operación matemática
		if(preg_match("/(\d+)\\".$value."(\d+)/",$string, $results)!=0){
			switch ($value) {
				case '+':
			        $resutado=($results[1])+($results[2]);
					break;
				case '-':
			        $resutado=($results[1])-($results[2]);
					break;
				case '*':
			        $resutado=($results[1])*($results[2]);
					break;
				case '/':
			        $resutado=round(($results[1])/($results[2]),2);
					break;	
				default:
					break;
			}
	}
	}
 //Se devuelve el resultado de la operación	
return $resutado;	
}

if(!empty($_POST['capt'])){
	$_SESSION["valor"]=rand(0,50);
}
//Se verifica la variable global
//si contiene datos,se generara las claves
if(!empty($_SESSION["valor"])){
	if(strlen($_SESSION["valor"])>0){
	//Instancia de la clase
    $PasswordLib = new PasswordLib\PasswordLib();
    //Se guarda en la variable la operación matemática
    $numaleatorio=NumerAletorios();
    //Se incripta el resultado devuelto
    //de la operacion matematica
    $hash = $PasswordLib->createPasswordHash(Operacion($numaleatorio));
     //Enviamos informacion para que se almacene 
        //en el navegador del usuario
	setcookie('captcha',$hash,time()+60*3);
        //Se imprimi la operación matemática para 
        //mostrar al usuario en el formulario de login 
	if(NumerAletorios()!=""){
		echo '{"retornar":"'.$numaleatorio.'"}';
	}else{
		echo '{"retornar":false}';
	}
	}
}
?>

Ay un ejemplo mas que no mostré en este articulo por el cual me parece demás, pero explicare en unas cuantas palabras, se usa métodos para crear imagen en PHP eso es la única diferencia, el cual dejare para que se descarguen los ejemplos completos.

Archivos:Descargar

Sobre el autor
Rodrigo Chambi Q.

Desarrollador de aplicaciones web y de escritorio, amante de la tecnología y autodidacta, me gusta conocer otras tecnologías, escribir artículos para compartir en la web y para estar al tanto en los nuevos paradigmas, respeto las políticas de software privativo y libre, ya que estas políticas son las normas que permite el desarrollo tecnológico social de la humanidad. filvovmax@gmail.com -- info@gitmedio.com

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Comentarios

  1. De Carlos Fabian Alonso

    Responder

  2. De Armando

    Responder

    • De Rodrigo

      Responder

  3. Responder