Ir al contenido principal

Gestión de perfiles y permisos en aplicaciones Web

Cuando se desarrollan aplicaciones web (o de escritorio si es del caso) que requieren manejo de usuarios, una de las características más comunes a incluir es la de asignar permisos a cada usuario dependiendo de su rol o perfil dentro de la aplicación. A continuación se describen algunas sugerencias para una correcta administración y asignación de estos permisos.

Comencemos por establecer el comportamiento de estos llamados “permisos”. Básicamente, se trata de permitir a un usuario el poder acceder a una característica como por ejemplo el editar registros de una tabla particular, por ejemplo “inventario”. Así, un usuario que tenga en su perfil asignado el acceso a “inventario/editar” podrá hacerlo, en tanto aquel que no lo tenga, no podrá realizar esta actividad. Así las cosas, podemos relacionar el permiso con un menú asociado, en este caso “inventario/editar”, igual puede hacerse con “inventario/listar”, “inventario/adicionar”, “inventario/asignar-responsable” u otras acciones similares para otras tablas o servicios de la aplicación. Esto significa que debemos definir en algún lugar todos los posibles menús que serán usados. Téngase presente que estos menús pueden estar o no directamente asociados a un script particular, como por ejemplo “/control/inventario/editar.php” (veremos un poco más sobre esto más adelante).

Ahora bien, si has prestado atención (y estoy seguro que lo has hecho) habrás notado que al declarar el menú he usado “inventario/editar” y no “editar/inventario”. Esto para que de esta forma todos los menús relacionados con el manejo de la tabla “inventario” sean del tipo “inventario/xxxx”, donde “xxxx” representa la acción de interés, así se hace más fácil el encontrar los menús que corresponden a acciones sobre una tabla o servicio en particular. Por supuesto, pueden declararse tantos niveles como se quieran, por ejemplo “inventario/elemento/retirar” o similares, y aunque puede verse como una forma de organizar una sección de menú en la interfaz de usuario de la aplicación, esto debería ser una consecuencia y no la razón de ser de la misma, porque recordemos que los menús mostrados en pantalla pueden organizarse de muchas diferentes formas según la interfaz de usuario que se esté usando. Así que mi recomendación es siempre agrupar los menús teniendo presente su funcionalidad primero que todo.

Pasemos entonces a resolver la inquietud de “¿dónde debo almacenar mi listado de menús?”. Si estamos usando bases de datos para registro de usuarios, seguro el primer pensamiento será el de incluir una tabla con ese listado base de menús. Y aunque puede ser una aproximación válida en muchos escenarios, es una que no comparto por la siguiente razón: imagina que tu aplicación está instalada en varios clientes y necesitas instalar una actualización en la que se adicionan nuevos menús. Si tu listado de menús base (todavía no hemos entrado a la parte donde se configuran para cada usuario, paciencia) se encuentra en una tabla de la base de datos, tendrás que incluir un script o secuencia de comandos adicional solamente para adicionar ese nuevo listado. Ahora bien, si el listado es tomado de un archivo incluido con los otros archivos o scripts que serán copiados durante la actualización, no requerirás ningún trabajo adicional, simplificando y reduciendo puntos de falla en dicho proceso de actualización. Así pues, la recomendación es usar un archivo dentro del repositorio de scripts, ya sea en formato texto plano, CSV, archivos .ini, JSON u otro formato de tu preferencia (como usuario Windows que soy y por su fácil manejo, me inclino usualmente por archivos .ini). Por ejemplo:

inventory/edit = /control/inventory/actions/edit.php
inventory/item/remove = /control/inventory/remove.php
inventory/item/detach = /control/inventory/remove.php?deta=1

Sugerencia para desarrolladores: Asociar el path del menú con la ubicación del script puede ser una forma rápida de invocar dicho script, aunque también puede usarse el archivo de definiciones para indicar a qué script corresponde cada menú y evitar así las limitaciones de verse forzado a crear un script para cada menú, tal como se muestra en el ejemplo de arriba.

Una vez se haya leído la lista de menús disponibles, en tu sistema de Administración de usuarios puedes ya proceder a vincularlos a cada usuario, usando el método que mejor se acomode a tu sistema (ahora si, lo ideal sería mediante vínculos entre tablas de una base de datos). Si tienes varios usuarios que tendrán acceso a los mismos menús, quizás prefieras no realizar la asociación usuario→menú, sino algo intermedio, crear primero un listado de (adivinas?) perfiles. Pero, ¿a qué hace referencia “perfiles” en este contexto? Pues a una agrupación de menús disponibles designados con nombres característicos como “Administrador”, “visitante” o “usuario básico”, entre otros. De esta forma, la asociación a realizar será usuario→perfil→menú.

Ya para terminar, hay que tener presente que pueden existir usuarios con privilegios o excepciones especiales y que a pesar de pertenecer a un determinado perfil, requieran que les sean asignados menús adicionales o por el contrario, bloquear alguno ya permitido. En este caso, la solución podría ser una de las siguientes:

  •  Crear un nuevo perfil. Sin embargo, es posible que la aplicación tenga algunas acciones que por seguridad (o por decisiones “creativas”) solamente se permitan a usuarios con un perfil especifico y al asignarle uno diferente dejaría al usuario sin posibilidad de usarlo aun cuando tenga el permiso asignado.
  • Asignarle al usuario menús adicionales o restringir el uso de ciertos menús, de forma que se use primero la relación usuario→perfil→menú y luego se complemente con los adicionales que encuentre y/o excluya las excepciones, cada una asignada en una relación directa del tipo usuario→menú.
  • Permitir asignar al usuario más de un perfil (como sucede con muchos Sistemas Operativos).

Resumiendo:

  • Crear un listado con todas las opciones de menú permitidas en la aplicación.
  • Registrar el listado de opciones validas en un archivo texto (CSV, INI, JSON u otro).
  • Crear una administración de perfiles donde se asocien los menús.
  • Incluir en la administración de usuario la asociación al perfil de interés, ya sea en una relación de uno a uno o de uno a varios, entre usuarios y perfiles.
  • Opcionalmente, incluir para cada usuario la opción de asignar menús extra o excluir menús incluidos en el perfil.

¡Y eso es todo, amigos! Con estas sugerencias ya solo queda a) sentarse y buscar en Internet el administrador de perfiles que mejor se acomode a tus necesidades o b) codificar uno propio, ¿qué prefieres?

Si te gustó este contenido y te ha resultado útil, si tienes alguna observación o consideras que requiere alguna corrección o si simplemente quieres dejar un saludo, no dudes en dejar un  comentario, será un gesto apreciado y de esta forma ayudas a mejorar estos contenidos.

¡Hasta una próxima!

Imagen de fondo cortesía de Pixabay.

Comentarios

Entradas populares de este blog

Manejo de clases globales únicas en PHP

¿Cómo acceder desde cualquier script en tu proyecto a Clases y/o funciones de uso común? Este puede ser una de las primeras directrices a establecer para cualquier proyecto porque siempre, siempre , sea en  PHP  u otro lenguaje, será necesario usar recursos comunes. En PHP existen diferentes alternativas para su manejo, ya sea por medio de variables globales o de clases/objetos estáticos. A continuación consideraremos una propuesta para este manejo. Creación de recursos globales Para ilustrar esta solución, partimos de la necesidad de implementar una librería para manejo de servicios relacionados con el servidor Web, que de forma amigable nos permita disponer de información como: Valores almacenados de la variable superglobal $_SERVER de PHP. Valores asociados a la consulta realizada por el usuario, por Ej. la dirección IP del usuario o la URL ingresada. Valores asociados al servidor web usado, por Ej. la dirección IP del servidor o la ubicación del script que ej...

Sesión de usuarios en aplicaciones web

Uno de los módulos más importantes y a la vez menospreciados cuando se aborda la tarea de crear un sitio web de servicios, ya sea para una intranet corporativa o un sistema de gestión de información ( SGI ) es la gestión y administración  requerida para una correcta implementación de sesiones de usuario. Y es que llevamos tanto tiempo usando usuarios y contraseñas en Internet, en cualquiera de sus muchas variaciones, que se asume muchas veces que esto ya forma parte del ADN de toda solución web y como tal, se destina muy poco tiempo y estudio a este apartado cuando se planifican las actividades de desarrollo. Lo cierto es que cada aplicación acostumbra desarrollar su propio esquema de manejo de sesiones y asumir que es algo superfluo puede equivaler a “pegarse un tiro en el pie”, especialmente cuando un módulo de este tipo se diseña desde ceros. Al referirse al manejo de sesiones de usuario suele pensarse únicamente en el proceso de capturar el nombre de usuario ( username ) y su ...

Caché de datos propios para agilizar ejecución de scripts PHP

De vez en cuando viene bien ayudar a PHP a generar respuestas de forma mucho más rápida y eficiente de lo que ya es capaz por si mismo. En mi opinión, la mejor forma de hacerlo es implementar un sistema de caché propio o (una opción un tanto más aburrida) reutilizar alguno ya existente. En este artículo detallaremos la implementación de una clase que permita este cometido. Aviso: Este artículo contiene ejemplos de programación en PHP aunque los conceptos explicados pueden ser aplicados a scripts realizados en cualquier otro lenguaje de programación. Para ilustrar este proceso, veamos el siguiente caso no tan hipotético: Una aplicación web hace uso de una API del clima. El resultado de la consulta es la misma para todos los usuarios y cambia solamente cada hora. Sin embargo, cada consulta tarda un tiempo promedio de 15 segundos. Esto implica que cada usuario deberá esperar esos 15 segundos para ver el resultado (sumado al tiempo que tome la visualización y otros procesos que deba real...