Mostrando entradas con la etiqueta Validación. Mostrar todas las entradas
Mostrando entradas con la etiqueta Validación. Mostrar todas las entradas

viernes, 28 de junio de 2013

Reglas propias para validación de formularios con CodeIgniter. Carga de archivos.

En el artículo anterior “Validación de formularios con CodeIgniter”, se comentaba sobre la importancia de validar los datos de entrada por formularios en nuestra aplicación web, así como sanearlos, formatearlos y prepararlos para la inserción en la base de datos, de forma que mantengamos la integridad de la BD y el funcionamiento del servidor y el sitio web.

Comentaba también sobre el uso del FormValidation de CodeIgniter, que nos permite asociar reglas existentes (como required) a los componentes visuales, con lo cual se mostrarán mensajes de errores predefinidos, a los cuales les podemos dar el formato de salida que queramos.

A todo esto, podemos adicionar reglas y mensajes propios, y es sobre esto que quiero compartir mis recientes experiencias.

Parto de la necesidad que tuve de subir al servidor un archivo de imagen (un avatar para los usuarios de mi sistema). Con el siguiente código incorporas el componente visual que te permite escoger un fichero.

<input type="file" name="userfile_pic" >

clip_image001

El input de tipo file permite seleccionar ficheros cuyos datos puedes acceder a través de las variables de php$HTTP_POST_FILES o $_FILESa partir de PHP 4.1.0. Por ejemplo puedes usar:

$HTTP_POST_FILES['userfile_pic']['name'];
//nombre original del fichero en la PC cliente
$HTTP_POST_FILES['userfile_pic']['type'];
//tipomime delfichero, ej. "image/gif"
$HTTP_POST_FILES['userfile_pic']['size'];
//tamaño del fichero


Lo primero que debes notar es que he usado el nombre del componente tipo file dentro del primer corchete. La mayoría de los ejemplos que puedas encontrar toman por defecto el nombre userfile, pero debes tener cuidado de que el nombre coincida con el que has puesto en la vista.

Si pruebas este código es probable que obtengas un mensaje de que no se ha seleccionado ningún fichero. En ese caso seguramente te faltó poner tu formulario comomultipart. Usando CodeIgniter lo pones así:

<?php echo form_open_multipart('direccion_fichero_script');?>

Bueno, si decides continuar con php básico, utilizas el is_uploaded_file(), que te sube el archivo y te retorna el error en caso de haberlo. Pero mi propósito es usar FormValidation para asegurarme de que el fichero es válido, usando el mismo mecanismo de validación que para el resto de los componentes visuales.

Para esto empleamos la clase de subir ficheros de CodeIgniter.En el siguiente ejemplo he indicado la carpeta hacia la que voy a subir el fichero en el servidor, el tipo de fichero que quiero recibir (* para cualquier tipo), el tamaño máximo de fichero y el ancho y alto, pues en mi caso voy a subir imágenes.El overwrite permite sobrescribir los ficheros en el servidor. He cargado la clase upload que trae CodeIgniter en una de sus bibliotecas, y al cargarla le he pasado mi configuración. También he capturado el error en caso de haberlo.do_uploadintentasubir el fichero.

function valid_file()

{

$config['upload_path'] = './uploads/';

$config['allowed_types'] = 'gif|jpg|png';

$config['overwrite'] = TRUE;

$config['max_size'] = '100';

$config['max_width'] = '1024';

$config['max_height'] = '768';

$this->load->library('upload', $config);

if ( ! $this->upload->do_upload()){

$error = array('error' => $this->upload->display_errors());



}

else



}


Hasta ahí el código funciona si el componente visual se llama userfile, que es el que espera CodeIgniter por defecto. Si el nombre es otro, como en mi ejemplo, basta decir:

$this->upload->do_upload('userfile_pic');


Bien, ahora transformaremos la función anterior para combinarla con FormValidation. Te pongo solamente el segmento que cambia:

function valid_file()

{



if ( ! $this->upload->do_upload('userfile_pic'))

{

$error = array('error' => $this->upload->display_errors());

$this->form_validation->set_message('valid_file',$error);

return FALSE;

}

else

{

return TRUE;

}

}

Si se cargó retorno TRUE, sino retorno FALSE y declaro que el mensaje de error para la función valid_file es $error. En lugar de $error puedes poner un mensaje propio, pero aquí reutilizo el que me retorna CodeIgniter que es más informativo.

Ahora creamos la regla para validar el componente userfile_pic. Esto lo pones en la función donde haces la validación de los demás componentes. El detalle está en ponerle callback_ a la función que hace el chequeo.

$this->form_validation->set_rules('userfile_pic', 'Imagen', 'callback_valid_file');

Esta es la manera de crear nuevas reglas, haces una función que revise lo que quieres validar y que retorna verdadero o falso (para que funcione el if ($this->form_validation->run() == FALSE)), y creas una regla poniendo callback_nombre_de_la_funcion.

Si resultó positivo puedes acceder al nombre del fichero, que ya está en el servidor, a través del mismo$_FILES['userfile_pic']['name'], y guardar el nombre en la base de datos.

Si quieres subir varios ficheros desde un mismo formulario, puedes ponerle a todos los input files el mismo nombre con corchete (ej. file_name[]), y accedes a ellos a través de:

$_FILES['filename']['name'][0];

$_FILES['filename']['name'][1];



O puedes ponerles nombres distintos y usar

$this->upload->do_upload('filename1');

$this->upload->do_upload('filename2');



Bueno, como puedes ver no es complicado crear nuevas reglas de validación. A la vez, hemos usado otra clase de CodeIgniter que nos permite cargar ficheros, demostrando así sus potencialidades para desarrollar sitios seguros, funcionales y con un código organizado, necesario para posteriores mantenimientos.

{ Leer Más }


lunes, 17 de junio de 2013

Validación de formularios con CodeIgniter

Una cuestión de suma importancia en toda aplicación web es la seguridad, tanto del propio sistema (que no produzca errores por sí mismo) como contra ataques de usuarios. Los usuarios pueden ser malintencionados o no y a veces los peores atacantes son los que no saben lo que están haciendo. Quizás para muchos internautas sea costumbre que si te piden una edad escribes un número, pero, ¿y si alguien pone letras?

La seguridad con los tipos de datos se logra a varios niveles. Primeramente, en el diseño de la base de datos, donde debes ajustar cada tipo de dato a lo que realmente necesitas. Una vez establecido esto, se deben validar los datos de entrada de usuarios para que coincidan con los de la base de datos, evitando así dos cosas, primero, el mensaje de error de base de datos, que como no supimos capturar nos sale de momento y rompe con todo nuestro diseño; y segundo, mantenemos la integridad de nuestra base de datos.

También debes hacer un diseño correcto de las vistas. Es muy recomendable utilizar cajas de selección (combobox) donde se despliegan las opciones posibles, y así evitamos que el usuario inserte valores ajenos. Si tiene que entrar Sí o No, pues es mejor utilizar un combobox con los dos valores, o una caja de chequeo (checkbox) donde marcado es Sí y no marcado es No. Hay maneras de evitar que el usuario escriba “sí”, “si”, “Sí”, “SI”, “s”, “yes”, “y”, etc. Debes indicar qué datos del formulario son obligatorios (suele usarse un asterisco), y de qué tipo son.

Queda entonces validar que no entren campos vacíos, y que los entrados sean válidos (números, fechas, direcciones web, direcciones http, etc.). Es pertinente validar los datos del lado del cliente (PC donde está el usuario), es decir, usando java script (una opción de moda es el jquery validate). Esta validación en el cliente permite que el usuario conozca sus errores antes de hacer el envío o submit de la página, lo que permite además conservar sin mucho trabajo los datos entrados en los componentes visuales.

Pero como hay diversos navegadores en los que las cosas se comportan a veces de formas diferentes, y porque el usuario puede tener deshabilitado el java script, es necesario validar los datos también en el lado del servidor: el php no depende de qué navegador se esté usando en los clientes, por lo que estamos trabajando en un entorno más controlado.

Cuando recibas el formulario puedes usar el tradicional $var = $_POST['component_name'] (recuerda que en el servidor se obtiene el valor del componente a través de su nombre, en el cliente se trabaja también con el ID del componente), y revisar los valores de tu variable. Aquí estoy asumiendo el envío de datos por POST, en vez de por GET.

Sin embargo, CodeIgniter brinda una excelente aproximación a la validación de datos, con la clase de validación de formularios. Esta clase permite especificar las reglas que le vas a aplicar a los datos enviados desde el cliente, así como los mensajes de error para cada una. Además permite especificar los delimitadores que le darán formato a tu mensaje, y da la posibilidad de mostrar los errores nuevamente en el cliente.

function X() //en el controlador

{

$this->load->library('form_validation');

$this->form_validation->set_rules('username', 'Username', 'required');

$this->form_validation->set_error_delimiters('<div class="error">', '</div>');

if ($this->form_validation->run() == FALSE) {

$this->load->view('myform');

}
else {

$this->load->view('formsuccess');

}

}
<?php echo validation_errors(); ?> //en la vista

 


En este ejemplo he cargado la clase form_validation; he especificado que el componente llamado username, que tiene adelante una etiqueta con el texto Username[1], es obligatorio (required); he configurado que el mensaje de error salga dentro de un <div> en vez de dentro de un <p> como está por defecto, y de paso he indicado una clase propia para el div, que responde a un estilo de css para mis mensajes de error. Finalmente verifico, si la validación da FALSE es que hubo error y cargo nuevamente la vista donde estaba mi componente username, sino cargo otra vista cualquiera.

En la vista “myform”, donde está el componente que se está validando, tendrías que poner echo validation_errors() para que muestre los mensajes de error. Lo usual es ponerlo antes de abrir tu formulario. Lógicamente si no hay errores no se muestra nada. También se puede mostrar los errores de forma independiente para cada componente, usando echo form_error('username'), en este caso puedes mostrar el mensaje al lado del componente.

El tipo required viene predefinido con CodeIgniter como otros tantos. CodeIgniter usa el segundo parámetro de la regla para completar el mensaje, en este caso se muestra algo así como “El campo Username es obligatorio”.

CodeIgniter permite también concatenar reglas usando “|” y preparar o formatear los datos. En el siguiente ejemplo se eliminan los espacios en blancos de los tres campos con trim, se marcan como obligatorios, se especifica que el campo username debe tener entre 5 y 12 caracteres y que el password y el passconf confirmado deben ser iguales. Finalmente se encripta la contraseña con md5.

$this->form_validation->set_rules('username', 'Username', 'trim|required|min_length[5]|max_length[12]');

$this->form_validation->set_rules('password', 'Password', 'trim|required|matches[passconf]|md5') ;

$this->form_validation->set_rules('passconf', 'Password Confirmation', 'trim|required');


Además se pueden crear reglas propias con sus respectivos mensajes, sobre lo cual comentaré mis experiencias en un próximo artículo.

Recuerda siempre que cuando hagas un submit debes validar tus datos, sanearlos de datos maliciosos, preformatearlos (trim, html encoded) y finalmente prepararlos para la inserción en la base de datos de forma que se mantenga su integridad, garantizando así esta parte de la seguridad de tu sistema.




[1] No tiene que ser necesariamente el nombre de la etiqueta, aquí usas un texto que le sea más entendible al usuario, de forma que cuando llegue el mensaje de error sepa de cual componente se le está hablando. Así que lo usual es que tenga el mismo texto de la etiqueta del componente.

{ Leer Más }


IconIconIcon