Como implementar reCaptcha con php

Captcha es el acrónimo de Completely Automated Public Turing test to tell Computers and Humans Apart (Prueba de Turing pública y automática para diferenciar máquinas y humanos). Toma ya!!

Se viene utilizando más o menos desde el año 2000 y hoy en día es casi esencial para evitar que muchos robots completen formularios web de forma automática y evitar buena parte del spam (de ahí que a estos robots también se les llamen spambots).

Básicamente Captcha consiste en una prueba de desafío para comprobar que quién está completando un formulario o interaccionando con otros elementos de una web es un humano y no una máquina. La prueba suele consistir en una imagen en la que se muestran caracteres distorsionados y se pide que se introduzcan dichos caracteres de la imagen en un campo de texto de un formulario. Se supone que una máquina no es capaz de distinguir estos caracteres y que solo un humano puede hacerlo y, por tanto, superar la prueba.

Existen bastantes bibliotecas para implementar Captcha con php. Aquí voy a poner un ejemplo de implementación muy sencilla de Captcha en tu propio script php y también del servicio reCaptcha de Google. Ambos son válidos pero yo me decanto por el servicio de Google, es gratis, rápido y lleva opciones interesantes de accesibilidad como poder escuchar el código Captcha que, aunque también lo puedes implementar en tu propio script, es más engorroso. Además que un código Captcha no es infalible y reCaptcha de Google lo hace más seguro.

Implementación de Captcha con php

Para hacer tu propio captcha vamos a ver un ejemplo sencillo utilizando la biblioteca GD (extensión de php para trabajar con imágenes), por lo que necesitarás, además de tener instalado el motor php en tu servidor, tener la biblioteca GD.

1.- La imagen de fondo

Tenemos que tener una imagen que nos va a servir de fondo para nuestro Captcha. Esta imagen ha de contener un degradado, líneas o diferentes colores, o todo a la vez, con el objetivo de dificultar el trabajo a programas de identificación de caracteres.

Yo he elegido esta imagen:

Puedes crear tu propia imagen a tu gusto utilizando cualquier editor de imagen como Photoshop o el simple Microsoft Painting.

Utilizando la función php imagecreatefrompng() cargaremos nuestra imagen de fondo (si tu imagen está en otro formato, por ejemplo jpg, la función sería imagecreatefromjpeg(), consulta el manual GD).

$captchaImage = imagecreatefrompng("captcha.png");

 2.- Cadena de texto

Ahora tenemos que introducir un texto en la imagen. Podemos cargar un tipo de fuente determinado utilizando imageloadfont(). Tras cargar la fuente tenemos que crear una cadena de texto única. En el siguiente ejemplo se crea una cadena de caracteres utilizando uniqid(), pasándole hash MD5 y tomando los últimos 9 caracteres de la cadena generada. Tras la obtención de nuestro texto, guardamos el mismo en una variable de sesión. También se puede guardar en una base de datos. Introducimos el texto en la imagen de fondo de nuestro captcha con la función imagestring().

//Cargar una fuete desde un archivo
$captchaFont = imageloadfont("anonymous.gdf");

//Crear el texto para el captcha
$captchaText = substr(md5(uniqid('')),-9,9);

//Almacener el texto captcha en una variable de sesion
$_SESSION['session_captchaText'] = $captchaText;

//Elegir el color para el texto
$captchaColor = imagecolorallocate($captchaImage,0,0,0);

//Dibujar el texto sobre el fondo del captcha
imagestring($captchaImage,$captchaFont,15,5,$captchaText,$captchaColor);

 3.- Obtener la imagen con Captcha

Después de todos estos pasos, el output de la imagen es tan sencillo como:

imagepng($captchaImage);

 Podremos tener la imagen Captcha donde queramos con un código html de imagen normal:

<img src="/captcha.php" name="captcha" width="233" height="49" >

 4.- El formulario donde mostrar el código Captcha

Se trata de un formulario html y procesado con php. Únicamente decir que en el procesamiento del formulario compararemos la cadena de caracteres introducida en un input con la cadena de caracteres de la imagen Captcha, cadena que almacenamos anteriormente en una variable de sesión.

<?php session_start() ?>
<html>
 <body>
  <form method="post" action="">
   <img src="/captcha.php" alt="captcha image"/><br/>
   Introduzca los caracteres:<input type="text" name="captcha" size="9" maxlength="9">
   <input type="submit" value="Enviar">
  </form>
<?php
if(isset($_POST["captcha"])) {
  if($_SESSION["session_captchaText"]==$_POST["captcha"])
   {
    echo 'CAPTHCA correcto';
  } else {
    echo 'CAPTHCA incorrecto';
  }
}
?>
 </body>
</html>

Descarga el ejemplo de Captcha

Implementación de reCaptcha con php

Si el anterior código es sencillo, implementar reCaptcha con php lo es mucho más. Lo primero es obtener una key de reCaptcha (es gratis) y puedes hacer aquí (te dan una key publica y otra privada). Después descargamos la biblioteca reCaptcha en php. En el propio paquete viene un ejemplo, yo os pongo aquí mi propio ejemplo.

Y nuestro formulario con reCaptcha quedará algo así:

  <html>
    <body>

      <form method="post" action="verify.php">
        <?php
          require_once('recaptchalib.php');
          $publickey = "key_publica";
          echo recaptcha_get_html($publickey);
        ?>
        <input type="submit" />
      </form>

 </body> </html>

 En el lado del servidor procesamos el formulario y comprobamos el código reCaptcha del siguiente modo:

 <?php
  require_once('recaptchalib.php');
  $privatekey = "your_private_key";
  $resp = recaptcha_check_answer ($privatekey,
                                $_SERVER["REMOTE_ADDR"],
                                $_POST["recaptcha_challenge_field"],
                                $_POST["recaptcha_response_field"]);

  if (!$resp->is_valid) {
    //Código para ejecutar cuando reCaptcha es incorrecto
         echo $resp->error;
  } else {
    //Código para realizar cuando reCaptcha es correcto
  }
  ?>

La implementación de reCaptcha con php no puede ser más fácil, ¿verdad?

Descarga ejemplo de implementación de reCaptcha



Comentarios (5)

Community Builder Avatar
cybnet
(27.03.2012 (17:20:44))
Sí No Citando "Alfredo " :
valida bien pero en un momento me da el error "Could not open socket"

Te podría decir cómo solucionar este error pero cómo antes de preguntar has estado enviando mensajes puramente de SPAM te quedas con tu duda chavolote o que te la solucione otro.
Community Builder Avatar
Alfredo
(27.03.2012 (14:01:16))
Consulta por que no me funciona Sí No Hola, baje todo lo que indicas y procedi a ejecutar valida bien pero en un momento me da el error "Could not open socket" que esto o como se soluciona. Saludos
Community Builder Avatar
cybnet
(15.02.2012 (11:12:11))
Sí No Saludos wiskyrock,

Cómo puedes observar en el código de ejemplo, reCaptcha o el otro ejemplo de captcha propio, se ponen en un formulario, así que puedes meter el código que muestra el input correspondiente al Captcha dentro de tu formulario de registro. Luego, en el servidor, en el script que maneja los datos del formulario de registro introduces una nueva comprobación, la comprobación del Captcha introducido, tal y como se hace en el ejemplo.
Community Builder Avatar
wiskyrocknroll
(14.02.2012 (18:50:34))
Implementarlo a un codigo de registro en php Sí No y como seria para implementarlo a un script php de registro?
Community Builder Avatar
cybnet
(03.02.2012 (10:45:46))
Error trabajando en local Sí No Citando "invitado" :
la verdad, no soy muy evolucionado, creo que involuciono a veces, pero al fin y al cabo, estoy armando un petit foro. Dije, uh, que bueno, a ver?
descargué, y me mandá de lleno como si no existiera el captcha, (trabajando en "localhost") codo codo,
tal vez en el apuro de ver como viene la onda me estoy omitiendo un paso... pero lo que pusieron para descargar no me funcionó :S
help?


No lo había probado en local, acabo de probar los dos ejemplos que hay para descargar y funcionan perfectamente tanto en local como en mi servidor.
¿Qué quieres decir lo de "me manda de lleno"? ¿Te has instalado php y apache, o lo que uses para montar tu web, en local?

Smileys

:confused::cool::cry::laugh::lol::normal::blush::rolleyes::sad::shocked::sick::sleeping::smile::surprised::tongue::unsure::whistle::wink: