En este tutorial, el objetivo es hacer un «click» en el captcha para validar que el formulario no haya sido rellenado por un robot.
Vamos a necesitar dos imágenes:
La Imagen de seguridad:
La imagen de la máscara de Captcha:
A continuación pondre el codigo explicado:
- <?php
- // iniciamos la session
- session_start();
- // declaramos nuestras variables
- $width = 180;
- $height = 90;
- $blob_width = 40;
- $blob_height = 40;
- // creamos nuestra imagen
- $image = imagecreatetruecolor($width, $height);
- //color background de la imagen
- $white = imagecolorallocate($image, 230, 230, 230);
- $red = imagecolorallocate($image, 255, 0, 0);
- $blue = imagecolorallocate($image, 0, 0, 230);
- // llenamos el contenedor de la imagen
- imagefilledrectangle($image, 0, 0, $width, $height ,$white);
- // creamos el background de espirales para nuestra imagen
- $theta = 1;
- $thetac = 7;
- $radius = 16;
- $circles = 20;
- $points = 32;
- for ($i = 0; $i < ($circles * $points) - 1; $i++)
- {
- $theta = $theta + $thetac;
- $rad = $radius * ($i / $points );
- $x = ($rad * cos($theta)) + $x_axis;
- $y = ($rad * sin($theta)) + $y_axis;
- $theta = $theta + $thetac;
- $rad1 = $radius * (($i + 1) / $points);
- $x1 = ($rad1 * cos($theta)) + $x_axis;
- $y1 = ($rad1 * sin($theta )) + $y_axis;
- imageline($image, $x, $y, $x1, $y1, $blue);
- $theta = $theta - $thetac;
- }
- // obtenemos la posicion de nuestro circulo aleatoriamente
- $x_axis = rand($blob_width, $width) - ($blob_width / 2);
- $y_axis = rand($blob_height, $height) - ($blob_height / 2);
- // dibujamos el circulo
- imagefilledellipse ($image, $x_axis, $y_axis, $blob_width, $blob_height, $red);
- // creamos la imagen de mascara
- $mask_image = imagecreatetruecolor($width, $height);
- // escogemos el color de nuestro background y color de circulo para nuestra mascara
- $mask_white = imagecolorallocate($mask_image, 255, 255, 255);
- $mask_red = imagecolorallocate($mask_image, 255, 0, 0);
- // llenamos la imagen mascara con nuestro background
- imagefilledrectangle($mask_image, 0, 0, $width, $height ,$mask_white);
- // dibujamos el circulo en nuestra mascara
- imagefilledellipse ($mask_image, $x_axis, $y_axis, $blob_width, $blob_height, $mask_red);
- // escribimos la imagen en el buffer
- ob_start();
- imagepng($mask_image);
- $mask_image_data = ob_get_contents(); // recibimos los datos y limpiamos el buffer
- ob_end_clean();
- // convertimos la imagen a Base64
- $mask_image_data_b64 = base64_encode($mask_image_data);
- // guardamos los datos en nuestra variable del servidor
- $_SESSION['captcha_image_code'] = $mask_image_data_b64;
- // Enviamos las cabeceras del contenido
- header('Content-type: image/jpeg');
- header('Cache-control: no-cache');
- // lanzamos la imagen al navegador
- imagejpeg($image);
- imagedestroy($image);
- ?>
Ahora el formulario:
- <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">
- <p>Name<br/><input type="text" name="name" /></p>
- <p>Comment<br/><textarea name="message"></textarea></p>
- <p>
- Click the Red Circle to continue:<br/>
- <input type='image' name='submit' src='captcha.php' alt='Captcha Security' />
- </p>
- </form>
Por ultimo la validacion:
- session_start();
- if(isset($_POST['submit_x']) && isset($_POST['submit_y'])) {
- if(!empty($_POST['name']) && !empty($_POST['message'])) {
- // retrive the image captcha data
- $data = base64_decode($_SESSION['captcha_image_code']);
- $captcha_image = imagecreatefromstring($data);
- $x = $_POST['submit_x'];
- $y = $_POST['submit_y'];
- // get the pixel color of the clicked x and y coordinate
- $rgb = imagecolorat($captcha_image, $x, $y);
- $color_tran = imagecolorsforindex($captcha_image, $rgb);
- // check if the color is red and red only
- $captcha_ok = ($color_tran['red'] == 255 && $color_tran['green'] == 0 && $color_tran['blue'] == 0 && $color_tran['alpha'] == 0) ;
- if($captcha_ok) {
- $result = "Thank you for submitting your comment.";
- } else {
- $result = "Please make sure you click the red circle!";
- }
- } else {
- $result = "Please fill out the entire form.";
- }
- }
Un cambio adicional aquí es recuperar la imagen de la máscara de la sesión y volver a poner esa imagen de un objeto y luego obtener el color del píxel de X e Y.
Para ello, primero tenemos que recuperar la imagen de la máscara de la sesión y luego descifrar como se muestra a continuación:
- // retrive the image captcha data
- $data = base64_decode($_SESSION['captcha_image_code']);
A continuación, convertirlo de nuevo en una imagen del objeto utilizando la funcion ImageCreateFromString().
- $captcha_image = imagecreatefromstring($data);
Luego recuperar la coordenadas X e Y desde el primer clic que el usuario envía, junto con el color del píxel usando imagecolorsforindex (). Nos aseguramos de que sólo se obtiene un color rojo y nada más.
- // obtenemos el color del pixel que fue clickeado con las coordenas "x" y "y"
- $rgb = imagecolorat($captcha_image, $x, $y);
- $color_tran = imagecolorsforindex($captcha_image, $rgb);
- // verificamos que el color sea solo rojo
- $captcha_ok = ($color_tran['red'] == 255 && $color_tran['green'] == 0 && $color_tran['blue'] == 0 && $color_tran['alpha'] == 0) ;
Despues de todo esto el formulario nos quedaria asi:
- <?php
- session_start();
- if(isset($_POST['submit_x']) && isset($_POST['submit_y'])) {
- if(!empty($_POST['name']) && !empty($_POST['message'])) {
- // retrive the image captcha data
- $data = base64_decode($_SESSION['captcha_image_code']);
- $captcha_image = imagecreatefromstring($data);
- $x = $_POST['submit_x'];
- $y = $_POST['submit_y'];
- // get the pixel color of the clicked x and y coordinate
- $rgb = imagecolorat($captcha_image, $x, $y);
- $color_tran = imagecolorsforindex($captcha_image, $rgb);
- // check if the color is red and red only
- $captcha_ok = ($color_tran['red'] == 255 && $color_tran['green'] == 0 && $color_tran['blue'] == 0 && $color_tran['alpha'] == 0) ;
- if($captcha_ok) {
- $result = "Thank you for submitting your comment.";
- } else {
- $result = "Please make sure you click the red circle!";
- }
- } else {
- $result = "Please fill out the entire form.";
- }
- }
- ?>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>Captcha Demo</title>
- </head>
- <body>
- <?php if(!empty($result)) echo "<div style='color:#990000; margin-bottom: 20px;'>" . $result . "</div>"; ?>
- <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">
- <p>Name<br/><input type="text" name="name" /></p>
- <p>Comment<br/><textarea name="message"></textarea></p>
- <p>
- Click the Red Circle to continue:<br/>
- <input type='image' name='submit' src='captcha.php' alt='Captcha Security' />
- </p>
- </form>
- </body>
- </html>
Ahora puedes implementarlo en tu web, puedes cambiar los colores y jugar un poco con esta validacion, veras que no es muy dificil.
Leave A Comment
You must be logged in to post a comment.