El método utilizado para el envío de los datos al servidor, indicará como viajan los datos hacia él.
A) GET
- Todos los nombres de los campos y valores viajan por la URL (query strings).
- Como son mostrados por la URL el navegador los almacena en su historial. Lo que no es muy conveniente para el caso de información sensible y más si ese ordenador puede ser usado por más personas. Además que el usuario despistado puede compartir datos al compartir la URL.
- Debido a esta hay una restricción de longitud de los datos. La longitud máxima de la URL es de 2048 caracteres.
- Los datos enviados al servidor, al viajar por la URL, pueden quedar almacenados en los ficheros de 'logs' del mismo.
- Solo se permite enviar datos ASCII.
- Resultados de operaciones GET pueden ser cacheadas. Lo que quiere decir que múltiples llamadas a un servicio pueden resultar una única petición.
- Tipo de codificación (enctype): application/x-www-form-urlencoded. Es el tipo por defecto, además del único, por lo que no es necesario indicarlo.
B) POST
- Todos los nombres de los campos y valores viajan en el cuerpo de la petición HTTP.
- No hay limite de longitud de los datos.
- Datos no expuestos en URL o 'logs' de servidor.
- Permite en envió de información de tipo binario. Lo que lo hace apto para el envió de ficheros.
- No se puede cachear operaciones POST.
- Tipo de codificación: application/x-www-form-urlencoded, por defecto, y multipart/form-data para envió de ficheros.
En cuanto a seguridad, ninguno de ellos aporta una mejora real de seguridad respecto al otro. Si bien es cierto que el POST no expone información a través de la URL o 'logs' del servidor, la información igual viaja en texto plano. Aunque evidentemente es mejor utilizar POST para el envío de datos sensibles y dejar GET para simples peticiones de información. Para una verdadera seguridad necesitaríamos usar certificados y HTTPS.
Vamos a partir del siguiente formulario html:
<div id="contacto">
<fieldset>
<legend>Formulario de contacto</legend>
<form action="contacto.php" method="post">
<p>
<label for="nombre">Nombre</label>
<input type="text" name="nombre" id="nombre" />
</p>
<p>
<label for="telefono">Num. Teléfono</label>
<input type="text" name="telefono" id="telefono" />
</p>
<p>
<label for="email">Email</label>
<input type="text" name="email" id="email" />
</p>
<p>
<label for="mensaje">Mensaje</label>
<textarea name="mensaje" id="mensaje"></textarea>
</p>
<p>
<input type="submit" id="enviar" value="Enviar"/>
</p>
</form>
</fieldset>
</div>
Cuando el formulario es enviado, los nombres de los campos del formulario y sus valores viajan en el cuerpo de la petición POST hacia el servidor. Más concretamente hacia contacto.php. Dicha petición podría ser parecida a esta:
POST /contacto.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: localhost/prueba.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 43
nombre=Jose&telefono=123456789&email=ejemplo@prueba.com&mensaje=hola...&enviar=Enviar
Todas las variables (nombre,telefono...) serán accesibles desde el script PHP en el servidor. Ya que serán almacenadas en el array superglobal asociativo $_POST. Si se hubiera usado GET como método de envío, accederíamos a las variables mediante el array superglobal $_GET.
Por lo tanto para acceder al valor de dichas variables accederíamos así $nombre = $_POST['nombre'], $email = $_POST['email']...
Desde PHP 5.3 la directiva de configuración de PHP 'register_globals' fue declarada obsoleta y por lo tanto desactivada por defecto. Ya que permitía la creación de variables remotamente. Y aunque tenía la ventaja de crear automáticamente variables para cada uno las claves de dichos arrays asociativos de $_POST o $_GET. Esto supone un fallo de seguridad. No se podía que permitir que los parámetros que se enviaban a través de la URL se convirtiesen automáticamente en variables al llegar al servidor.
Validación
Vamos a ver como podemos validar los datos provenientes del formulario. No vamos a tener en cuenta la inyección de sql u otros problemas de seguridad. Nos centraremos en una simple validación mediante expresiones regulares.
Para ello utilizaremos la siguiente función de PHP:
preg_match_all(string $patronBusqueda, string $cadena )
Mediante esta función trataremos de buscar la concordancia del patrón especificado (primer parámetro) en la cadena (segundo parámetro).
Ejemplos de utilización:
- Validar nombre. Puesto que se es posible insertar nombre y apellidos vamos a permitir solo caracteres y espacios en blanco. También añadiremos para el ejemplo una comprobación de máximo de caracteres. Y un mínimo de 3 caracteres.
function validarCadena($cadena,$max){
$expr = '/^[a-zA-Z ]{3,}$/';
if(preg_match($expr, $cadena) && strlen($cadena)<=(int)$max) return true;
else return false;
}
- Validar teléfono. Vamos a suponer que se puede insertar tanto móvil como fijo (formato de España).
function validarTelefono($telefono){
$expr = '/^[9|8|6|7][0-9]{8}$/';
return preg_match($expr, $telefono);
}
- Validar email.
function validarEmail($email) {
$expr = '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/';
return preg_match($expr, $email);
}
Ejemplo de utilización
function validarCadena($cadena, $max) {
$expr = '/^[a-zA-Z ]{3,}$/';
if (preg_match($expr, $cadena) && strlen($cadena) <= (int) $max)
return true;
else
return false;
}
function validarEmail($email) {
$expr = '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/';
return preg_match($expr, $email);
}
function validarTelefono($telefono) {
$expr = '/^[9|8|6|7][0-9]{8}$/';
return preg_match($expr, $telefono);
}
$errores = array();
$cadenaErrores = "";
if (isset($_POST['nombre'], $_POST['telefono'], $_POST['email'], $_POST['mensaje'])) {
$nombre = $_POST['nombre'];
$telefono = $_POST['telefono'];
$email = $_POST['email'];
$mensaje = $_POST['mensaje'];
$max = 60;
if (!validarCadena(trim($nombre), $max))
$errores[] = "El nombre solo admite letras y espacios en blanco. Debe de contener entre 3 y $max caracteres.";
if (!validarTelefono($telefono))
$errores[] = "El número de teléfono introducido no es válido";
if (!validarEmail($email))
$errores[] = "El email introducido no es válido";
if (empty($errores)) {
//hacer algo con los datos
} else {
//cadena con todos los errores que podemos devolver al cliente
foreach ($errores as $error) {
$cadenaErrores .= "<p>$error</p>";
}
}
}
La función trim(string $cadena) elimina los espacios en blanco al principio y al final de la cadena. Ya que estos espacios en blanco no nos interesan para la validación Solo nos pueden llegar a interesar los espacios en blanco entre caracteres (para el nombre).
Otras validaciones útiles
- Validar fecha con formato DD/MM/AAAA
function validarFecha($fecha){
$expr = '/^\d{1,2}\/\d{1,2}\/\d{4}$/';
return preg_match($expr, $fecha);
}
- Validar contraseña. Supondremos unos requisitos: mínimo de 8 caracteres y al menos de un carácter en minúscula, uno en minúscula y un dígito
function validarConstraseña($pass){
$expr = '/^.*(?=.{8,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$/';
return preg_match($expr, $pass);
}
Mirar el uso de declaraciones de búsqueda hacia adelante en expresiones regulares.
- Funciones destinadas a validar un tipo concreto de valor. Destinadas por ejemplo a saber si se ha introducido una edad valida o una cantidad:
- is_string(): Función que retornará true si la variable evaluada es una cadena.
- is_int(): Función que retornará true si la variable evaluada es un entero.
- is_float():Función que retornará true si la variable evaluada es un flotante.
- is_numeric: Función que retornará true si la variable evaluada es un número o un string numérico.
- is_boolean(): Función que retornará true si la variable evaluada es de tipo bool.
No hay comentarios:
Publicar un comentario