Ir al contenido principal

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 contraseña a través de una página de inicio de sesión (login), pero se omiten otras consideraciones que no son menos importantes al momento de crear un sistema estable y robusto.

A continuación enumero los que considero son factores a considerar para un desarrollo de estos, sin que eso signifique que sea un listado absoluto, ni más faltaba. Pueden haber elementos adicionales a incluir o algunos que podamos no requerir para nuestro desarrollo particular, pero que cuando menos deberían evaluarse para evitar después pasar un mal trago.

Sin más preámbulos, comencemos:

  1. ¿Qué elemento se usará para autenticar el usuario en su ingreso al sistema?
    • Correo electrónico.
    • Nombre de usuario.
    • Documento de identidad (Ej. cédula de ciudadanía, número de pasaporte).
    • Usando el API de un tercero (Google, Facebook).
    • Otro.
    • Varios o todos los anteriores? (quién dijo “miedo”, ¿ah?)
  2. Para el ingreso de la contraseña durante el inicio de sesión:
    • ¿Se enviará la contraseña sin cifrar o codificada usando md5 (no recomendado ya que actualmente este método se considera como obsoleto y poco seguro), sha256 o algún otro método de codificación de una vía? 
    • No se usará contraseña, se enviará un código SMS al celular y/o correo electrónico del usuario para completar el proceso de autenticación.
    • ¿Se usará autenticación de dos factores (2FA)? Esto adiciona una capa adicional de seguridad al requerir tanto la contraseña como la validación de un código SMS enviado al celular y/o correo electrónico del usuario.
  3. Del lado administrativo, tener en cuenta para la gestión de contraseñas la implementación de:
    • ¿Cómo se guardará la contraseña en base de datos? (sugerencia: Evitar siempre guardar la contraseña real en texto plano sin codificar).
    • Políticas de seguridad para el uso de contraseñas? (forzar longitud mínima y/o máxima, uso de mayúsculas, números, caracteres especiales, etc.).
    • Proceso de recuperación en caso de olvido por parte del usuario (usualmente implica el cambio de la contraseña anterior previa validación de la identidad del usuario, usualmente mediante envío de código SMS al celular y/o correo electrónico).
    • Permitir el cambio de la contraseña por parte del usuario.
    • Forzar el cambio de contraseña específicamente a un usuario, manualmente requerido por el administrador del sistema.
    • Forzar el cambio de contraseña a todos los usuarios del sistema (por Ej. cuando se deba cambiar el algoritmo de encripción de contraseñas o el método de registro al sistema).
    • Forzar el cambio automático de contraseña por política de seguridad (Ej. cambiarla cada 30 días).
  4. ¿Cómo se controla la duración de la sesión del usuario?
    • Tiempo finito, luego de vencido se da cierre a la sesión actual y se forza su reingreso.
    • Terminar la sesión por inactividad (Ej. el han pasado 10 minutos sin hacer click en algún enlace del sistema). Esto puede prevenir que información sensible pueda quedar expuesta cuando la persona no está haciendo uso de la aplicación.
    • Terminar la sesión automáticamente cuando se cierre la ventana del navegador (requiere control particular sobre las cookies usadas).
    • Tiempo infinito, es decir, la sesión no termina a menos que el usuario realice el cierre manualmente (o se limpien las cookies de sesión en el navegador). Esta opción puede ser en algunos casos activada manualmente por el usuario desde el formulario de inicio de sesión.
  5. ¿Qué datos complementarios mínimos se requieren para cada usuario? (Estos son datos no dependientes de la aplicación web particular pero requeridos para la gestión de usuarios).
    • Nombre real completo.
    • Nombres y apellidos por separado.
    • Correo electrónico.
    • Nombre de usuario (si aplica).
  6. Algunas consideraciones de seguridad a resolver:
    • ¿Puede el mismo usuario iniciar sesiones paralelas en el mismo navegador?
    • ¿Puede el mismo usuario iniciar sesiones paralelas en diferentes navegadores?
    • ¿Cada sesión iniciada cierra automáticamente cualquier sesión abierta previamente?
    • ¿Debe reportar por correo el inicio de cada sesión paralela?
    • ¿Debe reportar por correo cada inicio de sesión?
    • ¿Se hará bloqueo temporal de la cuenta luego de un número de intentos de inicio de sesión fallidos?
  7. Algunas estadísticas sugeridas para control y auditoría de los ingresos al sistema:
    • Al menos la fecha del último ingreso, pero se sugiere registrar cada ingreso y salida (o cierre).
    • Fecha, IP (opcional), usuario, tipo de autenticación y navegador (opcional) usados al iniciar sesión.
    • Fecha, usuario, sesión de inicio asociada y causa del cierre de sesión (manual, automático). 
    • Fecha, IP (opcional), usuario y causa del cambio de contraseña (manual, automático, etc.).
    • Fecha, IP (opcional) y usuario asociado a intentos de inicio de sesión fallidos.
  8. ¿Esta solución se usará para un sistema monoinstancia o de múltiples instancias cliente?
    • El usuario será compartido con varias aplicaciones web, cada una con su propia base de datos.
    • El usuario será para un único cliente en un sistema con diferentes clientes, cada uno con su propia base de datos y diferente manera de ingresar la contraseña.
    • Una combinación de las dos anteriores (un multiverso de la locura en si mismo).

Una vez evaluadas estas opciones y antes de sentarnos a escribir código como desaforados para nuestro nuevo módulo de gestión de usuarios, vale la pena tener en cuenta las siguientes observaciones:

  • Las contraseñas codificadas en el origen no se “traducen” usualmente sino que se validan en el servidor usando una “llave” de comparación, un método que sirve para adicionar una capa de seguridad pero que restringe la posibilidad de realizar controles del tipo “no usar la misma contraseña anterior como base” cuando se pide cambiar contraseña o la posibilidad de usarla para autenticarse en un sistema externo.
  • Cuando la autenticación no es local, es decir, no se validan localmente el usuario y contraseña (Ej. se usa Gmail, Facebook, LDAP, etc.) no se requiere guardar una contraseña pero seguramente si el ID asociado al sistema externo.
  • Algunos tipos de autenticación pueden requerir que la contraseña llegue en texto desde el formulario o codificada pero que sea recuperable (caso LDAP). Para estos casos particulares se recomienda siempre forzar el uso de protocolos seguros (https).
  • ¿Se solicitará la contraseña en la misma página que el nombre de usuario? Algunos sistemas primero solicitan el nombre de usuario. Si el nombre es valido y existe, se solicita la contraseña acompañada de información adicional (imagen o texto) que previamente el usuario ha ingresado, para que esté tranquilo de que si “está” en el lugar correcto y no en un sitio fraudulento.
  • Cuando se termine forzadamente una sesión de usuario, se recomienda permitirle continuar con la actividad que estaba realizando antes del cierre. Por ejemplo, si estaba guardando datos de un formulario, permitirle autenticarse y después de eso terminar el proceso de guardado sin tener que pedirle de nuevo los datos, de esta forma se evita generar incomodidad e inconformidad en el uso del sistema cuando ocurran estos casos de cierre.
  • Cada elemento potencialmente parametrizable (tiempo de duración de la sesión, políticas de seguridad para contraseñas, etc.) requerirá de un espacio en la aplicación web para que pueda ser fijado por el administrador del sistema.
  • Los datos complementarios del usuario (nacionalidad, género, dirección, etc.) deberían almacenarse en un espacio independiente y relacionarse al usuario autenticado. Esto facilita que el módulo de usuarios pueda ser reusado en diferentes sistemas ya que no todos requerirán los mismos datos complementarios del usuario.

Y ahora que ya tenemos una idea más completa de todos los posibles condicionales involucrados en la implementación de un módulo de gestión de usuarios, podemos realizar un mejor estimado del tiempo y el esfuerzo que su desarrollo habrá de tomar.

Si te gustó este contenido y te ha resultado útil, si tienes alguna observación o consideras que requiere alguna corrección, por favor házmelo saber en los comentarios. 

Hasta una próxima!

Imagen de Mohamed Hassan provista por Pixabay

Comentarios

Entradas populares de este blog

Configurando el servicio PHP

En el capítulo anterior ( PHP con Apache sobre Windows ) vimos como configurar PHP para ejecutarse desde un servidor web usando Apache. A continuación veremos los elementos a configurar directamente en PHP para garantizar una ejecución responsable y sin tropiezos de nuestros scripts. Algunos se preguntarán ¿ por qué  molestarse en configurar manualmente PHP cuando frameworks como Laravel  ya te entregan un docker con todo preinstalado y preconfigurado? Bueno, la verdad prefiero tener control de qué está ejecutándose en mi maquina y no me gusta, en lo particular, requerir de un entorno propietario para cada aplicación desarrollada cuando puedo tener uno para todas y no desperdiciar espacio en disco , memoria y/o procesador  ejecutando en cada proyecto un servidor wen y/o PHP por separado. Si, se que muy probablemente soy una minoría en este aspecto, mea culpa . Y en segundo lugar, nunca se sabe cuando tendrás que entrar y ajustar tu configuración de PHP, así que cuando ese día ll

Cómo resolver y/o crear un Sudoku usando PHP (parte 1)

C omo programador, he tenido que realizar proyectos profesionalmente, algunos con mayores retos que otros. Pero aparte de los retos profesionales, existen retos personales, programas que me nace escribir ya sea porque necesito solucionar una necesidad puntual o solamente por el placer de hacerlo. Uno de esos últimos retos fue el de solucionar un Sudoku . Si ya se, existen muchas aplicaciones allí afuera que lo hacen, pero el reto es hacerlo, no copiarlo. Habiendo aclarado las intenciones al respecto, lo primero a tener claro es cómo se define un Sudoku. Para esto, voy a apoyarme en la siempre disponible (aunque no siempre fiable) Wikipedia: Un Sudoku estándar contiene 81 celdas, dispuestas en una trama de 9×9, que está subdividida en nueve cajas. Cada caja está determinada por la intersección de tres filas con tres columnas. Cada celda puede contener un número del uno al nueve y cada número solo puede aparecer una vez en cada fila, cada columna o cada caja. Un sudoku comienza con algu