26: Variables de Sesión
En los tutoriales anteriores logramos listar los usuarios desde la base de datos. Sin embargo, tenemos un grave problema de seguridad: cualquier persona puede acceder a la página usuario.php escribiendo la URL directamente en el navegador, sin necesidad de iniciar sesión.
http://localhost/tu_proyecto/index.php?action=usuarios
Esto no debería ser así. La sección de usuarios debe ser privada, accesible únicamente para quienes se hayan autenticado correctamente. Para resolver esto, utilizaremos variables de sesión en PHP.
¿Qué son las variables de sesión?
Las variables de sesión permiten mantener información a lo largo de la navegación del usuario por diferentes páginas de un sitio web. Cuando un usuario inicia sesión, podemos guardar un dato (por ejemplo, validar = true) que nos indique que está autenticado. Luego, en cada página privada, verificaremos si esa variable existe y es verdadera; si no, redirigiremos al usuario al formulario de ingreso.
¿Para qué sirven?
Para privatizar secciones de una aplicación.
Para controlar que solo usuarios registrados puedan acceder a ciertos contenidos.
Para implementar roles (administrador, editor, usuario común), aunque eso lo veremos más adelante.
Paso 1: Iniciar sesión al ingresar correctamente
Lo primero es modificar el controlador, específicamente el método ingresoUsuarioController. Cuando el usuario y la contraseña coincidan con los de la base de datos, debemos iniciar una sesión y crear una variable de sesión que llamaremos validar con el valor true.
Antes:
if($respuesta["usuario"] == $_POST["usuarioIngreso"] && $respuesta["password"] == $_POST["passwordIngreso"]){ header("location:index.php?action=usuarios"); }
Después:
public function ingresoUsuarioController(){ if(isset($_POST["usuarioIngreso"])){ $datosController = array( "usuario" => $_POST["usuarioIngreso"], "password" => $_POST["passwordIngreso"] ); $respuesta = Datos::ingresoUsuarioModel($datosController, "usuarios"); if($respuesta["usuario"] == $_POST["usuarioIngreso"] && $respuesta["password"] == $_POST["passwordIngreso"]){ // INICIAMOS SESIÓN session_start(); // CREAMOS UNA VARIABLE DE SESIÓN $_SESSION["validar"] = true; header("location:index.php?action=usuarios"); } else{ echo '<script>alert("Usuario o contraseña incorrectos");</script>'; } } }
Explicación:
session_start(): Inicia una nueva sesión o reanuda la existente. Debe llamarse antes de cualquier salida HTML (antes de cualquierechoo etiqueta).$_SESSION["validar"] = true;: Creamos una variable de sesión llamadavalidary le asignamos el valortrue. Esta variable estará disponible en todas las páginas mientras la sesión esté activa.
Paso 2: Proteger la página de usuarios
Ahora vamos a modificar la vista usuario.php. Antes de mostrar cualquier contenido, debemos verificar si la sesión está iniciada y si la variable validar es verdadera. Si no es así, redirigimos al usuario al formulario de ingreso.
Código para usuario.php:
<?php // Iniciamos la sesión para poder acceder a las variables de sesión session_start(); // Verificamos si la variable de sesión 'validar' NO existe o NO es verdadera if(!$_SESSION["validar"]){ // Si no está validado, redirigimos al formulario de ingreso header("location:index.php?action=ingresar"); // Finalizamos el script para que no se ejecute más código exit(); } ?> <h1>USUARIOS</h1> <table border="1"> <thead> <tr> <th>Usuario</th> <th>Contraseña</th> <th>Email</th> <th>Editar</th> <th>Borrar</th> </tr> </thead> <tbody> <?php // Aquí va el código que llama al controlador y muestra los usuarios $ingreso = new MvcController(); $ingreso->vistaUsuariosController(); ?> </tbody> </table>
Explicación:
session_start(): Necesario para acceder a$_SESSION.if(!$_SESSION["validar"]): El signo!significa negación. Preguntamos: "si NO es verdadero".header("location:..."): Redirige al navegador a otra página.exit(): Detiene la ejecución del script. Es una medida de seguridad para asegurar que no se ejecute código después de la redirección.
Prueba:
Cierra todas las ventanas del navegador para eliminar la sesión actual.
Intenta acceder directamente a
usuario.php(oindex.php?action=usuarios).Verás que automáticamente serás redirigido a
ingresar.php.
Paso 3: Crear la opción de salir (cerrar sesión)
Ahora necesitamos un botón o enlace para que el usuario pueda cerrar sesión. Cuando el usuario haga clic en "Salir", debemos destruir la sesión y redirigirlo al formulario de ingreso.
Crear el archivo salir.php en views/modules/:
<?php // Iniciamos la sesión para poder acceder a ella y destruirla session_start(); // Destruimos todas las variables de sesión session_destroy(); // Redirigimos al formulario de ingreso header("location:index.php?action=ingresar"); ?>
Explicación:
session_destroy(): Elimina todos los datos asociados a la sesión actual. Es como "cerrar la puerta con llave".
¿Dónde colocar el enlace para salir?
Normalmente en el menú de navegación (navegacion.php):
<nav> <ul> <li><a href="index.php?action=ingresar">Ingresar</a></li> <li><a href="index.php?action=registro">Registro</a></li> <li><a href="index.php?action=usuarios">Usuarios</a></li> <li><a href="views/modules/salir.php">Salir</a></li> </ul> </nav>
Prueba completa:
Inicia sesión correctamente (usuario: juan, password: 1234).
Serás redirigido a la página de usuarios.
Haz clic en "Salir".
Intenta volver a "Usuarios" desde el menú. Verás que te pide ingresar nuevamente.
Paso 4: Buenas prácticas de seguridad
Usar exit() después de header()
Después de una redirección con header(), es recomendable usar exit() para asegurar que el script se detenga y no se ejecute más código.
header("location:index.php?action=ingresar"); exit();
Cerrar conexiones de base de datos
Aunque PDO cierra automáticamente la conexión al finalizar el script, es una buena práctica cerrar explícitamente las conexiones para liberar recursos. Podemos hacerlo en el modelo.
Ejemplo en modelos.php:
public static function vistaUsuariosModel($tabla){ $stmt = Conexion::conectar()->prepare("SELECT id, usuario, password, email FROM $tabla"); $stmt->execute(); // Guardamos el resultado $resultado = $stmt->fetchAll(); // Cerramos la conexión (cerramos el statement) $stmt->closeCursor(); return $resultado; }
$stmt->closeCursor(): Cierra el cursor, liberando la conexión a la base de datos para que pueda usarse para otras consultas.
Resumen del Tutorial 26
Hemos aprendido a:
Iniciar sesión con
session_start()después de un ingreso exitoso.Crear variables de sesión (
$_SESSION["validar"] = true) para mantener el estado de autenticación.Proteger páginas privadas verificando la variable de sesión y redirigiendo si no está activa.
Cerrar sesión con
session_destroy().Aplicar buenas prácticas como
exit()después de redirecciones y cerrar conexiones concloseCursor().
Ahora nuestra aplicación distingue entre usuarios autenticados y no autenticados, dando un paso fundamental hacia una aplicación web segura y funcional.
Código completo de los archivos modificados
controlador.php (fragmento):
public function ingresoUsuarioController(){ if(isset($_POST["usuarioIngreso"])){ $datosController = array( "usuario" => $_POST["usuarioIngreso"], "password" => $_POST["passwordIngreso"] ); $respuesta = Datos::ingresoUsuarioModel($datosController, "usuarios"); if($respuesta["usuario"] == $_POST["usuarioIngreso"] && $respuesta["password"] == $_POST["passwordIngreso"]){ session_start(); $_SESSION["validar"] = true; header("location:index.php?action=usuarios"); exit(); } else{ echo '<script>alert("Usuario no encontrado");</script>'; } } }
usuario.php (vista protegida):
<?php session_start(); if(!$_SESSION["validar"]){ header("location:index.php?action=ingresar"); exit(); } ?> <h1>USUARIOS</h1> <table border="1"> <thead> <tr> <th>Usuario</th> <th>Contraseña</th> <th>Email</th> </tr> </thead> <tbody> <?php $ingreso = new MvcController(); $ingreso->vistaUsuariosController(); ?> </tbody> </table>
salir.php:
<?php session_start(); session_destroy(); header("location:index.php?action=ingresar"); exit(); ?>
En el próximo tutorial comenzaremos a trabajar con las operaciones de editar y borrar usuarios, siempre manteniendo la seguridad mediante las sesiones que acabamos de implementar.
Comentarios
Publicar un comentario