Diseño web: Una forma alternativa de crear un formulario de contacto con captcha propio

Un formulario de contacto es de esas cosas que nunca debemos descuidar en nuestra web o blog, si deseamos mantener la interacción con nuestros visitantes. Aunque en los blogs, como es el caso de WordPress (utilizado aquí), existen variados plugins para incluir formularios, los que estamos más introducidos en este mundillo sabemos bien de los pros y contras de utilizar las funciones de servidor para enviar correos electrónicos. Yo, particularmente, me inclino por mantener siempre bajo control todo aquello que pueda dar opción a la entrada o salida de basura a través de mis servidores.

La función  mail() de php puede ser vulnerable, y necesita casi siempre de alguna medida adicional de seguridad. Evitar la intromisión de los spambots se puede lograr mediante la escritura de un código elaborado, validando adecuadamente todos los campos y dotándoles de algún sistema captcha que pare cualquier spam antes de enviar el formulario. Pero también se puede prescindir directamente de esa función, echando mano del servidor SMTP para procesar los formularios de contacto. El presente artículo trata de cómo usar ambos métodos y de cómo integrar un sencillo sistema captcha propio.

 MÉTODO 1 – Usando nuestro servidor SMTP

El servidor SMTP con autenticación de salida es un método seguro para el envío de nuestros formularios. Además, apoyados en librerías como la phpmailer, la labor de diseño de nuestro formulario no sólo se simplificará, sino que tendremos variadas opciones añadidas para diversificar sus posibilidades.

Para distinguirlo de los numerosos formularios que podemos encontrar en la red, el que te presento hoy para este método lo he nombrado como «crafty-form», el cual colgaré públicamente con licencia GPL para quien desee hacer uso de él.

Aquí muestro una captura de cómo se ve el formulario

DE QUÉ SE COMPONE

Se compone de una única carpeta llamada «contacto» donde se guardan todos los archivos y que podrás renombrar si lo deseas. No obstante los archivos que contiene esta carpeta sí deben conservar su nombre original, ya que se encuentran vinculados entre sí.

La carpeta incluye los archivos siguientes:

Index.php
Acoge el código del formulario, las validaciones de los campos y un generador de imagen aleatorio).

contacto_enviar.php
Acoge el código php y la librería phpmailer para procesar el formulario.

class.phpmailer.phpclass.smtp.php
Son las librerías que nos permitirán configurar y procesar el formulario a través de un servidor SMTP. Las puedes descargar directamente desde la web oficial:
http://phpmailer.worxware.com/)*

estilos.css
Es una hoja de estilos muy sencilla para formatear nuestro formulario con CSS.

logo_contacto.gif
Es un logo de contacto.

logo_menuprin1.gif
Es un logo de retorno a la página principal de nuestra web.

– Imágenes objeto1.png hasta objeto12.png
Doce imágenes de verificación para el captcha en formato PNG.

*En el archivo RAR descargable de más abajo están todos los archivos necesarios para el funcionamiento de este formulario de contacto, incluidas las librerías phpmailer.

CÓMO FUNCIONA

Archivo index.php

En líneas generales, con index.php se despliega el formulario de contacto, se comprueban los campos del formulario mediante unas funciones de validación, y se muestra una pequeña imagen elegida al azar mediante un poco de código php.

Si los campos fueron validados correctamente, se llama a contacto_enviar.php pasándole una variable con el valor del campo captcha que haya escrito el usuario, al mismo tiempo que se le pasa también una variable de sesión con el número de imagen que se haya mostrado aleatoriamente. Se comparan ambas variables, y si no coinciden es que no se ha escrito correctamente el nombre del objeto mostrado; se muestra un mensaje y se da la opción de regresar para volver a introducir otro nombre. Si finalmente esta vez es correcto, se continúa con el proceso, que podemos ver en el apartado del archivo contacto_enviar.php

A continuación se muestra el código fuente de index.php:

[php]
<head>
<title>Formulario de Contacto</title>

<meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″ />
<link href=»estilos.css» rel=»stylesheet» type=»text/css»>

</head>
<body>

<!– FUNCIONES DE VALIDACIÓN DE LOS CAMPOS DEL FORMULARIO –>
<script Language=»JavaScript» Type=»text/javascript»>

function funcionesvalidar(theForm)
{

if (theForm.nombre.value == «»)
{
alert(«Escriba un valor para el campo \»nombre\».»);
theForm.nombre.focus();
return (false);
}

if (theForm.email.value == «»)
{
alert(«Escriba un valor para el campo \»email\».»);
theForm.email.focus();
return (false);
}

if (theForm.texto.value == «»)
{
alert(«Escriba un valor para el campo \»texto\».»);
theForm.texto.focus();
return (false);
}

if (theForm.miobjeto.value == «»)
{
alert(«Escriba un valor para el campo \»¿Eres humano?\».»);
theForm.miobjeto.focus();
return (false);
}
return (true);

}
</script>

<div align=»center»>
<div id=»wrap»>

<a href=»/index.php»>

<div class=»centrado»><img border=»1″ src=»logo_cabecera.jpg»></a><h1><img src=»logo_contacto.gif» align=»absmiddle»>&nbsp;
FORMULARIO DE CONTACTO</h1>
</div>

<hr color=»#0074C1″ size=»1″>

<!– GENERAMOS UN NÚMERO DE OBJETO AL AZAR –>
<?php
session_start();
$nobjeto = rand(1,12);
$_SESSION[‘nobjeto’]=»$nobjeto»;
$imagx = «objeto».$nobjeto.».png»;
?>

<!– MOSTRAMOS EL FORMULARIO DE CONTACTO –>

<form id=»form1″ name=»FrontPage_Form1″ method=»POST» action=»contacto_enviar.php» onsubmit=»return funcionesvalidar(this)» language=»JavaScript»>
<p><label for=»nombre»>Nombre:<br></label>

<input name=»nombre» type=»text» id=»nombre» size=»50″ /></p>
<p>

<label for=»email»>Email:<br>

<input name=»email» type=»text» id=»email» size=»40″ /></label></p>
<p>

<label for=»texto»>Texto:<br>

<textarea name=»texto» cols=»60″ rows=»6″></textarea><br>

<?php echo «<img src=’$imagx’>»; ?><br>
<label for=»humano»>¿Eres humano? Escribe abajo el nombre de este objeto<br>

<input name=»miobjeto» type=»text» id=»miobjeto» size=»40″ /></label></p>

<p align=»center»>
<input type=»submit» name=»Submit» value=»Enviar»/></p>

</form>

<p align=»center»>

<a target=»_top» href=»/index.php»>
<img border=»0″ src=»logo_menuprin1.gif»></a>

</div>
</div>
&nbsp;

</body></html>
[/php]

En el código anterior se incluye la opción de mostrar un logo de cabecera, para ello debes guardar en la misma carpeta del formulario una imagen con el nombre «logo_cabecera.jpg» con un ancho no superior a 700px.

Archivo contacto_enviar.php

Como ya expliqué este archivo es necesario para procesar los datos del formulario y validar el captcha, si es correcto se continúa hasta enviar el mensaje.

Una vez validado el captcha se capturan los valores de los campos del formulario, se configuran los datos para la librería phpmailer, y finalmente se arma el cuerpo del mensaje que se va a enviar. Aquí tienes que cambiar los valores del código por los tuyos, tales como el nombre de tu servidor SMTP, tu nombre de usuario SMTP, tu contraseña, el email a donde deseas que sea enviado el mensaje. También puedes indicar en el cuerpo del mensaje ($mail<Body) un texto que indique de dónde viene el formulario (ejemplo: «Mensaje enviado desde www.midominio.com»).

Finalmente se envía el mensaje, intentándolo hasta 3 veces si no se puede a la primera. Si concluyó con éxito se muestra el aviso de enviado, en caso contrario se mostrará un aviso de error.

En el código fuente de abajo están comentados los párrafos más significativos. Si aún así te surgieran dudas, puedes dejar comentarios al pie e intentaré solventarlas.

[php]
<head>
<meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″ />
<title>Formulario de contacto</title>
<link href=»estilos.css» rel=»stylesheet» type=»text/css»>
</head>
<body>

<?php

session_start();

// CREAMOS UN ARRAY Y DEFINIMOS LAS VARIABLES DE CADA OBJETO
$objeto = array();
$objeto[1]=»naranja»;
$objeto[2]=»dado»;
$objeto[3]=»mariposa»;
$objeto[4]=»pera»;
$objeto[5]=»fresa»;
$objeto[6]=»llave»;
$objeto[7]=»manzana»;
$objeto[8]=»pluma»;
$objeto[9]=»globo»;
$objeto[10]=»aguacate»;
$objeto[11]=»libro»;
$objeto[12]=»paraguas»;

// CAPTURAMOS EL OBJETO ESCRITO POR EL USUARIO
$miobjeto = $_POST[‘miobjeto’];

// CAPTURAMOS LA VARIABLE DEL OBJETO MOSTRADO
$nobjeto=$_SESSION[‘nobjeto’];

// COMPARAMOS EL OBJETO MOSTRADO CON EL DEL USUARIO
if ($miobjeto != $objeto[$nobjeto]) {

// EL OBJETO ESCRITO POR EL USUARIO NO ES CORRECTO
echo «<div id=’wrap’></br></br>El nombre del objeto es incorrecto</br><a href=’javascript:history.back()’>[VOLVER ATRÁS]</br></br></a></div>»;

exit();
}else{
// EL OBJETO ESCRITO POR EL USUARIO ES CORRECTO, VAMOS A ARMAR Y ENVIAR EL FORMULARIO

// CARGAMOS LA BIBLIOTECA PHPMAILER
require «class.phpmailer.php»;

// CAPTURAMOS LOS CAMPOS DEL FORMULARIO
$nombre = $_POST[‘nombre’];
$email = $_POST[‘email’];
$texto = $_POST[‘texto’];
$fecha = date(«d-M-y H:i»);

// CONFIGURAMOS LOS PARÁMETROS DE PHPMAILER
$mail = new phpmailer();
$mail->Mailer = «smtp»;
$mail->Host = «ESPACIO-PARA-EL-NOMBRE-DEL-SERVIDOR-SMTP»;
$mail­->Port = 587;
$mail->Timeout=30;
$mail->SMTPAuth = true;
$mail->CharSet = «UTF-8»;
$mail->Username = «NOMBRE-DE-USUARIO-SMTP»;
$mail->Password = «CONTRASEÑA»;

// ARMAMOS EL CUERPO DEL MENSAJE
$mail->From = $_POST[‘email’];
$mail->FromName = $_POST[‘nombre’];
$mail->AddAddress(«MIEMAIL@MIEMAIL.COM»);
$mail->Subject = «Formulario de contacto de…»;
$mail->Body = «
Mensaje enviado desde xxxxxxxx.com el «.$fecha.» </br>
——————————————————————— </br>
NOMBRE: «.$nombre.» </br>
E-MAIL: «.$email.» </br>
TEXTO: «.$texto.» </br>
——————————————————————— </br>
«;

// ENVIAMOS EL MENSAJE Y PROCESAMOS ERRORES
$mail->AltBody = $_POST[‘texto’];
$exito = $mail->Send();
$intentos=1;
while ((!$exito) && ($intentos < 3)) {
sleep(5);
//echo $mail->ErrorInfo;
$exito = $mail->Send();
$intentos=$intentos+1;
}

if(!$exito)
{

// MOSTRAMOS EL MENSAJE DE ERROR
echo «<font color=’#FFFFFF’>El servidor está sobrecargado y no se pudo enviar el mensaje en este momento, por favor inténtalo de nuevo más tarde</font>».$valor;
echo «<br>».$mail->ErrorInfo;

}
else
{

// MOSTRAMOS EL MENSAJE DE ENVÍO CORRECTO
echo «</br>»;
echo «</br>»;
echo «</br>»;
echo «</br>»;
echo «</br>»;
echo «</br>»;
echo «</br>»;
echo «</br>»;
echo «<div align=’center’><table cellspacing=’5′ cellpadding=’5′ bgcolor=’#00609F’><tr>
<td bgcolor=’#FFFFFF’> <p class=’fuente14pt azulon centrado’>¡Gracias!, el mensaje ha sido enviado</p>
<p align=’center’><a target=’_top’ href=’/index.php’><img src=’logo_menuprin1.gif’></a></td></tr></table></div>»;

}

}
?>

</body>
</html>
[/php]

Aclarar, que se pueden modificar, eliminar o añadir nuevos campos de formulario. Tienes que hacerlo en index.php y también en contacto_enviar.php; en éste debes hacerlo en el apartado de captura de los campos y también en el del cuerpo del mensaje.

Aquí te dejo un RAR descargable desde sourceforge.net, con todos los archivos operativos del formulario del método 1. Como ya expliqué simplemente tienes que cambiar/modificar los apartados correspondientes en el archivo contacto_enviar.php, tales como el nombre de tu servidor smtp, la contraseña o el email a donde deseas que sea enviado el formulario.

Descargar –> https://sourceforge.net/projects/crafty-form/

MÉTODO 2 – Usando la función mail() del servidor

Como ya vimos, en el método 1 utilizamos para el formulario nuestro propio servidor SMTP, la librería phpmailer, y condicionamos el envío mediante un captcha de imágenes. Ahora, en el método 2 utilizaremos la función mail() de nuestro servidor php, añadiendo un campo oculto para el usuario pero no así para los spambot.

El aspecto del formulario es casi idéntico al que se muestra al principio en el método 1, la única diferencia visual es que no se ve ningún campo de verificación ni imagen captcha. En su lugar, se utiliza un campo que ocultamos de la vista del usuario mediante CSS, para que no pueda cubrirlo. Lo que nos interesa precisamente es que ese campo no sea nunca cubierto por un usuario real; esta ausencia de contenido del campo al ser procesado nos indicará que estamos en presencia de un humano. Si no se tratase de tal, ese campo sería leído y se intentaría rellenar con datos; al hacerlo estarían descubriendo su naturaleza «no humana» (es un spambot), evidencia que aprovecharemos para detenerlo antes de que el formulario sea enviado.

Para distinguirlo de los numerosos formularios que podemos encontrar en la red, el que te presento como método 2 lo he nombrado como «hidden-form», el cual colgaré públicamente con licencia GPL para quien desee hacer uso de él.

DE QUÉ SE COMPONE

Se compone de una única carpeta llamada «contacto» donde se guardan todos los archivos y que podrás renombrar si lo deseas. No obstante los archivos que contiene esta carpeta sí deben conservar su nombre original, ya que se encuentran vinculados entre sí.

La carpeta incluye los archivos siguientes:

Index.php
Acoge el código del formulario y las validaciones de los campos.

contacto_enviar.php
Acoge el código php para procesar el envío del formulario.

estilos.css

Es una hoja de estilos muy sencilla para formatear nuestro formulario con CSS; uno de esos estilos se encargará de ocultar el campo de verificación que permite detectar los spambot.

logo_contacto.gif
Es un logo de contacto.

logo_menuprin1.gif
Es un logo de retorno a la página principal de nuestra web.

*En el archivo RAR descargable más abajo están todos los archivos necesarios para el funcionamiento de este formulario de contacto.

CÓMO FUNCIONA

Archivo index.php

En líneas generales, con index.php se despliega el formulario de contacto y se comprueban los campos del formulario mediante unas funciones de validación. Si los campos fueron validados correctamente, se llama al archivo contacto_enviar.php.

A continuación se muestra el código fuente de index.php:

[php]
<head>
<title>Formulario de contacto</title>

<link href=»estilos.css» rel=»stylesheet» type=»text/css»>

</head>
<body>

<!– FUNCIONES DE VALIDACIÓN DEL FORMULARIO –>
<script Language=»JavaScript» Type=»text/javascript»>

function FrontPage_Form1_Validator(theForm)
{

if (theForm.nombre.value == «»)
{
alert(«Escriba un valor para el campo \»nombre\».»);
theForm.nombre.focus();
return (false);
}

if (theForm.email.value == «»)
{
alert(«Escriba un valor para el campo \»email\».»);
theForm.email.focus();
return (false);
}

if (theForm.texto.value == «»)
{
alert(«Escriba un valor para el campo \»texto\».»);
theForm.texto.focus();
return (false);
}

}
</script>

<div align=»center»>
<div id=»wrap»>

<a href=»/index.php»>

<div class=»centrado»><img border=»1″ src=»logo_cabecera.jpg» width=»700″></a><h1><img src=»logo_contacto.gif» align=»absmiddle»>&nbsp;
FORMULARIO DE CONTACTO</h1>
</div>

<hr color=»#0074C1″ size=»1″>

<form id=»form1″ name=»FrontPage_Form1″ method=»POST» action=»contacto_enviar.php» onsubmit=»return FrontPage_Form1_Validator(this)» language=»JavaScript»>
<p><label for=»nombre»>Nombre:<br></label>

<input name=»nombre» type=»text» id=»nombre» size=»50″ /></p>
<p>

<label for=»email»>Email:<br>

<input name=»email» type=»text» id=»email» size=»40″ /></label></p>
<p>

<label for=»texto»>Texto:<br>

<textarea name=»texto» cols=»60″ rows=»6″></textarea><br>

</label>
<label for=»verificacion» class=»verif»>Deja este campo en blanco (es sólo como medida antispam)</label>
<input name=»verificacion» class=»verif» /></p>
<p>

<label for=»texto»>
<input type=»submit» name=»Submit» value=»Enviar»/></p>

</form>

<p align=»center»>

<a target=»_top» href=»/index.php»>
<img border=»0″ src=»logo_menuprin1.gif»></a>

</div>
</div>
&nbsp;

</body></html>
[/php]

Archivo contacto_enviar.php

Una de las condiciones para que el formulario sea enviado, es que el campo llamado «verificacion» del archivo contacto_enviar.php se mantenga en blanco antes del envío. Se sabe, que los spambot pueden «leer» el campo de un formulario aunque éste permanezca oculto para un usuario real; en consecuencia el spambot intentará leerlo y cubrir el campo con algún dato. Ésto es precisamente lo que nos permitirá detectarlo y pararlo. Para ello, simplemente comprobamos que el campo «verificacion» está vacío; si es así procesamos el formulario, en caso contrario se trata de un spambot y paramos el envío.

A continuación se muestra el código fuente de contacto_enviar.php:

[php]
<html>
<head>
<link href=»estilos.css» rel=»stylesheet» type=»text/css»>
<title>Enviar formulario de contacto</title>
</head>
<body>

<?php

session_start();

$mail1=’tuemail@tudominio.com’; //EMAIL A DONDE ENVIAR EL MENSAJE
$asunto=»Mensaje de contacto»; //TEXTO DEL ASUNTO DEL MENSAJE

if ($_POST[‘verificacion’] != «»){
// PARECE UN SPAMBOT / VOLVER SI HA SIDO CUBIERTO POR UN USUARIO REAL
echo «<div id=’wrap’></br></br>El campo Verficación debes dejarlo en blanco (es una medida contra el spam)</br><a href=’javascript:history.back()’>[VOLVER ATRÁS]</br></br></a></div>»;
exit();

}else{

// VERIFICADO QUE ES UN USUARIO REAL, ENVIAMOS EL FORMULARIO
$nombre = $_POST[‘nombre’];
$email = $_POST[‘email’];
$texto = $_POST[‘texto’];
$ip=$_SERVER[‘REMOTE_ADDR’];
$fecha = date(«d-m-y»);
$hora = date(«H:i»);

$cuerpo = «
$asunto enviado el $fecha a las $hora
IP de origen: $ip
————————————————————————————-
NOMBRE: «.$nombre.»
E-MAIL: «.$email.»
TEXTO: «.$texto.»
————————————————————————————-
«;

$exito = mail($mail1, $asunto, $cuerpo, «From: $email\n»);

if($exito)
{
echo «</br>»;
echo «</br>»;
echo «</br>»;
echo «</br>»;
echo «</br>»;
echo «</br>»;
echo «</br>»;
echo «</br>»;
echo «<div align=’center’><table cellspacing=’5′ cellpadding=’5′ bgcolor=’#00609F’><tr>
<td bgcolor=’#FFFFFF’> <p class=’fuente14pt azulon centrado’>¡Gracias!, el mensaje ha sido enviado</p>
<p align=’center’><a target=’_top’ href=’/index.php’><img src=’logo_menuprin1.gif’></a></td></tr></table></div>»;
}
else
{
//echo «<font color=’#FFFFFF’>El servidor no pudo enviar el mensaje en este momento, por favor inténtalo de nuevo más tarde</font>»;
}

}
?>

</body>
</html>
[/php]

——————

¿Te gusta? pincha para compartir en tus redes sociales….

Abel Domínguez

MI canal de Youtube: https://www.youtube.com/c/AbelElTecnotron

2 comentarios:

  1. jose luis vasquez

    hola me gusta el diseño del formulario.¿pero como puedo modificar el codigo para usalo sin imagen captcha?

  2. El Tecnotrón (Twitter: @El_Tecnotron)

    Jose Luis, la razón de ser de este formulario es utilizarlo con un captcha. Si deseas prescindir de él (no se recomienda si lo vas a utilizar en tus sitios), tienes que eliminar, por una parte, el código que muestra los objetos en index.php; y por otra parte, todo el código donde se hace la comparación de los objetos mostrados en contacto_enviar.php. Si no se provoca la comparación, el formulario será enviado sin limitaciones.

Deja una respuesta

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