Ir al contenido principal

AJAX y PHP Seguridad con Captcha

Tema Anterior: http://superahacker.blogspot.com/2009/09/ajax-y-php-formulario-de-envio-de-e.html

En un tema anterior mostrabamos un ejemplo de como validar formularios html con php haciendo uso de AJAX, en esta oportunidad vamos ampliar la idea. vamos a incluir seguridad con captcha la idea mejorar nuestra seguridad.





Cree un archivo con el nombre de index.html y en el coloque el codigo a continuación, observe los 3 bloques comentados.
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Simple AJAX Contact Form | Superahacker ©</title>
<script type="text/javascript">
var http = false;
if(navigator.appName == "Microsoft Internet Explorer") {
http = new ActiveXObject("Microsoft.XMLHTTP");
}else 
{http = new XMLHttpRequest();}


function checkform(name, email, subject, content, captcha)
{http.abort();

http.open("GET", "contact.inc.php?name=" + name + "&email=" + email + "&subject=" + subject + "&content=" + content + "&captcha=" + captcha, true);
http.onreadystatechange=function() {if(http.readyState == 4) {document.getElementById('ajaxresponse').innerHTML = http.responseText;}
if(http.readyState == 1) 
{document.getElementById('ajaxresponse').innerHTML = '<img src="loading.gif" alt="Loading" />';}}http.send(null);}


</script>
<style type="text/css">
body, td {font-family: Lucida Grande, Lucida Sans Unicode, sans-serif;font-size: 12px;color: #444;}
input, textarea {background: #EEE;border: 1px solid #DDD;padding: 3px;color: #666;font-size: 12px;font-family: Lucida Grande, Lucida Sans Unicode, sans-serif;width: 200px;}
input.button {width: 100px;border: 1px solid #CCC;cursor: pointer;}
input:hover, textarea:hover {border: 1px solid #ECFF9F;background: #FEFEFE;}
input:focus, textarea:focus {border: 1px solid #C3DF53;background: #FEFEFE;}
div#ajaxresponse {margin-bottom: 10px;min-height: 15px;}span#error {color: #CF5A5A;}
span#success {color: #6D8F1A;}
</style>
</head>
<body>
<h2>Simple AJAX Contact Form</h2>
<div id="ajaxresponse"></div>
<form action="" method="post">
<table>
<tr>
<td>Nombre</td><td><input type="text" name="name" id="name" />
</td>
</tr>
<tr>
<td>Email</td><td><input type="text" name="email" id="email" />
</td>
</tr>
<tr>
<td>Asunto</td><td><input type="text" name="subject" id="subject" />
</td>
</tr>
<tr>
<td>Mensaje</td><td><textarea cols="" rows="" name="message" id="message"></textarea></td>
</tr>


<tr>
<td><img src="captcha.php" ></td>

<td><input type="text" name="captcha" id="captcha"  maxlength="4" />
</td></tr>

<tr>
<td><input type="reset" value="Limpiar Form" class="button" />
</td>


<td><input type="button" value="Enviar Mensaje" class="button" onClick="checkform(document.getElementById('name').value, document.getElementById('email').value, document.getElementById('subject').value, document.getElementById('message').value,document.getElementById('captcha').value)" />
</td>

</tr>
</table>
</form>
</body>
</html>

Luego para validar el envio de los datos lo haremos con un archivo php llamado "conctact.inc.php" y en coloque el codigo a continuación, observe los bloques comentados.

Nota: Por un error del Blog la funcion empty() de php se duplica en emptyempty() traten de copiar el codigo usando los controles [view plain].
<?php
/*!-- © 1er. Bloque --*/
/*!-- © Iniciamos sessiones por que necesitar extraer un valor de la session
--*/
session_start(); 
/*!-- © End 1er. Bloque --*/

/* RETARDO PARA PODER APRECIAR LA IMAGEN */
sleep(1);

/* CONFIG */

/* WEBMASTERS EMAIL */
$target = "superahacker@gmail.com";
$targetname = "Alex F. Torres Ch.";
$subjprefixe = true; 
$subjprefix = "[Contacto | Superahacker ©]";

/* VARIABLES */
$name = $_GET['name'];
$email = $_GET['email'];
$subject = $_GET['subject'];
$content = $_GET['content'];
/*!-- © 2do. Bloque --*/
/*!-- © Extraemos el captcha --*/
/*!-- pasado por metodo GET escrito por el usuario --*/
$captcha = $_GET['captcha']; 
/*!-- y el captcha pasado en una variable session --*/
$captchaVer = $_SESSION['captcha'];
/*!-- © End 2do. Bloque --*

/* CHECKING DETAILS */
if(empty($name) && empty($email) && empty($subject) && empty($content) && empty($captcha)) {
echo '<span id="error">Por favor ingrese todos los datos.</span>';
}elseif(empty($name)) {
echo '<span id="error">Por favor ingrese su nombre</span>';
}elseif(empty($email)) {
echo '<span id="error">Por favor ingrese su email</span>';
}elseif(empty($subject)) {
echo '<span id="error">Por favor ingrese su asunto</span>';
}elseif(empty($content)) {
echo '<span id="error">Por favor ingrese su mensaje</span>';
}

/*!-- © Tercer Bloque --*/
/*!-- © verificamos el captcha no este vacio --*/
elseif(empty($captcha)) {
echo '<span id="error">Por favor ingrese el codigo de seguridad</span>';}
/*!-- © End Tercer Bloque --*/
elseif(!preg_match( "/^([a-zA-Z0-9])+([a-zA-Z0-9._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9._-]+)+$/", $email)) {
echo '<span id="error">Por favor ingrese un email valido.</span>';
}elseif(strlen($name) < 3) { 
echo '<span id="error">tu nombre debe ser mayor a 3 caracteres.</span>'; 
}elseif(strlen($email) < 9) { 
echo '<span id="error">tu email debe ser mayor a 9 carcateres.</span>'; 
}elseif(strlen($subject) < 3) { 
echo '<span id="error">tu asunto debe ser mayor a 3 caracteres.</span>'; 
}elseif(strlen($content) < 20) { 
echo '<span id="error">tu mensaje debe ser mayor de 20 caracteres.</span>'; 
} 
/*!-- © 4to. Bloque --*/
/*!-- © Si la longitud de captcha es mayor a 3 --*/
elseif(strlen($captcha) < 4) { 
echo '<span id="error">el codigo de seguridad esta imcompleto.</span>'; 
}
/*!-- © Si captcha escrito es igual a de la session --*/
elseif($captcha !== $captchaVer) { 
echo '<span id="error">el codigo de seguridad es incorrecto.</span>'; 
}
/*!-- © End 4to. Bloque --*/
else{

/* EMAIL */
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= 'To: ' . $targetname . ' <' . $target . '>' . "\r\n";
/* TARGET EMAIL AS SENDER TO MAKE SURE IT'S NOT IN THE SPAM FOLDER */
$headers .= 'From: ' . $name . ' <' . $target . '>' . "\r\n";
$headers .= 'Reply-To: ' . $name . ' <' . $email . '>' . "\r\n";
if($subjprefixe == true) {
$subject = $subjprefix . " " . $subject;
}
$message = '<html><head><title>' . $subject . '</title>
<style type="text/css">
body, td {font-family: Lucida Grande, Lucida Sans Unicode, sans-serif;font-size: 12px;color: #444;background: #EEE;}
</style>
</head>
<body>
<p>
<b>Sender:</b> ' . $name . ' <' . $email . '><b>Asunto:</b> ' . $subject . '<b>Mensaje:</b>' . nl2br($content) . '</p><p>--Mensaje enviado el ' . date("d/m/Y H:i:s") . '</p></body></html>';

if(mail($target, $subject, $message, $headers)) {
echo '<span id="success">Mensaje Enviado</span>';
}else {
echo '<span id="error">Ocurrio un error mientras enviábamos el email.</span>';}}
?>

Para generar la imagen captcha cree un archivo php llamado "captcha.php" y en coloque el codigo a continuación.
<?php
session_start(); 
/* START SESSION */
$width = 50; 
/* IMG WIDTH (PX) */
$height = 20; 
/* IMG HEIGHT (PX) */
$characters = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789"; 
/* CHARACTERS FOR CAPTCHA STRING */
$font = "font.ttf"; 
/* FONT LOCATION */
$fontS = 11; 
/* FONT SIZE (PX) */
$min = 25; 
/* MIN NUMBER FOR THE RANDOM RGB TEXT COLOR */
$max = 200; 
/* MAX NUMBER FOR THE RANDOM RGB TEXT COLOR */
$eBorder = true; 
/* ENABLE BORDER, "true" TO ENABLE & "false" TO DISABLE */
$eLines = true; 
/* ENABLE LINES, "true" TO ENABLE & "false" TO DISABLE (RECOMMENDED TO ENABLE)*/
$MiLC = 200; 
/* MIN LINE COLOR */
$MaLC = 250; 
/* MAX LINE COLOR */
$maxLines = 10; 
/* MAX LINES (RECOMMENDED BETWEEN 5 & 15)

/* ADVANCED */
$positionCharacterX = 3; 
/* POSITION CHARACTER 1 ON THE X-AXIS (PX)*/
$characterSpace = 12; 
/* SPACE FOR 1 CHARACTER (PX)*/
$positionCharactersY = 16; 
/* SPACE ON THE Y-AXIS (PX)*/

/* FUNCTION TO SELECT A RANDOM CHARACTER OUT OF A STRING */
function random_char($string) {
$length = strlen($string);
$position = mt_rand(0, $length - 1);return $string[$position];}
$img = imagecreate($width, $height);imagecolorallocate($img, 255, 255, 255); 

/* BACKGROUND COLOR IN RGB */
$randNr1 = rand($min, $max); 
/* RANDOM NUMBER 1 BETWEEN min & max */
$randNr2 = rand($min, $max); 
/* RANDOM NUMBER 2 BETWEEN min & max */
$randNr3 = rand($min, $max); 
/* RANDOM NUMBER 3 BETWEEN min & max */
$randomChar1 = random_char($characters); 
/* RANDOM CHARACTER 1 */
$randomChar2 = random_char($characters); 
/* RANDOM CHARACTER 2 */
$randomChar3 = random_char($characters); 
/* RANDOM CHARACTER 3 */
$randomChar4 = random_char($characters); 
/* RANDOM CHARACTER 4 */
$textcolor1 = imagecolorallocate($img, $randNr1, $randNr2, $randNr3); 
/* TEXT COLOR 1 */
$textcolor2 = imagecolorallocate($img, $randNr2, $randNr3, $randNr1); 
/* TEXT COLOR 2 */
$textcolor3 = imagecolorallocate($img, $randNr3, $randNr1, $randNr2); 
/* TEXT COLOR 3 */
$textcolor4 = imagecolorallocate($img, $randNr3, $randNr2, $randNr1); 
/* TEXT COLOR 4 */
if($eLines == true) {
for($i=0; $i <= $maxLines; $i++) {
$linesC = imagecolorallocate($img, rand($MiLC, $MaLC), rand($MiLC, $MaLC), rand($MiLC, $MaLC));
imageline($img, rand(0, $width), rand(0, $height), rand(0, $width), rand(0, $height), $linesC);
}
}
if($eBorder == true) {
$bColor = imagecolorallocate($img, 175, 175, 175); 
/* BORDER COLOR IN RGB */
imageline($img, 0, 0, $width, 0, $bColor);
imageline($img, 0, $height, 0, 0, $bColor);
imageline($img, $width-1, 0, $width-1, $height, $bColor);
imageline($img, $width-1, $height-1, 0, $height-1, $bColor);
}
imagettftext($img, $fontS, 0, $positionCharacterX + 0 * $characterSpace, $positionCharactersY, $textcolor1, $font, $randomChar1); 

/* CHARACTER 1 */
imagettftext($img, $fontS, 0, $positionCharacterX + 1 * $characterSpace, $positionCharactersY, $textcolor2, $font, $randomChar2); 
/* CHARACTER 2 */
imagettftext($img, $fontS, 0, $positionCharacterX + 2 * $characterSpace, $positionCharactersY, $textcolor3, $font, $randomChar3); 
/* CHARACTER 3 */
imagettftext($img, $fontS, 0, $positionCharacterX + 3 * $characterSpace, $positionCharactersY, $textcolor4, $font, $randomChar4); 
/* CHARACTER 4 */
$_SESSION['captcha'] = $randomChar1 . $randomChar2 . $randomChar3 . $randomChar4; 
/* CAPTCHA STRING FOR SESSION */
header("content-type: image/png"); 
/* CONTENT TYPE */
imagepng($img); 
/* CREATE IMAGE */
imagedestroy($img); 
/* DESTROY IMAGE */
?>


y copie esta imagen en el mismo directorio llamada "loading.gif" para la animación de el proceso mientras se intenta recoger datos del servidor.


Por ultimo copie el archivo font.ttf en el mismo directorio para la fuente captcha, puede bajarlo desde [aqui]

Para ver el ejemplo ingrese a esta dirección http://superahacker.webcindario.com/ajax004/index.php

Nota Se hace uso de la función imagecreate() de php para ello se requiere que el servidor web tenga instalada librerias GD, en el caso de web.espana.es es un servidor web gratuito y no incluye esas librerias.

Comentarios

Entradas más populares de este blog

JSP y MySQL Conexion a Base de Datos

Tema anterior: http://superahacker.blogspot.com/2009/06/instalacion-netbeans-glassfish.html El modulo JSP con conexion a una base de datos MySQL, tiene las siguientes caracteristicas usar una clase Java llamada "Customers" que se encuentra en un package llamado "Mypackage" , para usar sus metodos y con ellos llevar acabo una consulta.

JSP y MsSQL Conexion a Base de Datos

Tema anterior: http://superahacker.blogspot.com/2009/09/jsp-y-mysql-conexion-base-de-datos.html El modulo JSP con conexion a una base de datos Ms SQL Server, tiene las siguientes caracteristicas usar una clase Java llamada "Customers" que se encuentra en un package llamado "Mypackage" , para usar sus metodos y con ellos llevar acabo una consulta.

FreeTDS para el acceso a MsSQL desde PHP en Linux CentOS 5

Tema Anterior: http://superahacker.blogspot.com/2009/04/instalacion-de-unixodbc-para-la.html En esta ocasion la situación es como conectar con PHP 5 desde un Servidor Linux a una base de Datos Ms Sql Server en Servidor Windows.