2.2Sesiones, cookies y autenticación simple
Lo esencial en 30 segundos
- HTTP lo olvida todo: cada petición es independiente — cookies y sesiones añaden la «memoria» entre páginas (quién está conectado, cesta, preferencias).
- Sesiones para lo sensible, cookies para las preferencias: datos de confianza del lado del SERVIDOR ($_SESSION, no modificables) — nunca un dato sensible en una cookie modificable.
- Contraseñas con hash, nunca en claro: password_hash en la inscripción, password_verify en la conexión, ID de sesión regenerado — sin ninguna excepción.
Minicaso hilado — Riad mantiene conectados a sus miembros
Riad continúa con su formulario (2.1): los miembros de la asociación deben seguir conectados de una página a otra para ver su espacio personal. Como HTTP no tiene estado, añade una memoria: una cookie para la preferencia de idioma (no sensible), una sesión para la identidad (sensible, lado del servidor). Al conectarse comprueba la contraseña con password_verify sobre un hash, regenera el ID de sesión, guarda el identificador en $_SESSION; cada página protegida comprueba la sesión. En 2.3, factorizará la comprobación en un archivo incluido en todas partes; en 2.4, fechará la última conexión.
Continuación del hilo 2.1: el formulario de Riad se convierte en un espacio de miembros con memoria — y continúa en 2.3 y 2.4.
1. Dar una memoria a HTTP: cookies y sesiones
El protocolo HTTP es sin estado (stateless): cada petición es INDEPENDIENTE, el servidor no «recuerda» nada entre dos páginas. Para memorizar un estado (quién está conectado, una cesta, preferencias), dos mecanismos. Las cookies: pequeños datos guardados en el NAVEGADOR, reenviados al servidor en cada petición — creadas con setcookie(), leídas en $_COOKIE. Lado del cliente, por tanto VISIBLES y MODIFICABLES por el usuario: reservadas a datos no sensibles (idioma, tema), con opciones de seguridad (HttpOnly contra el robo por XSS, Secure solo para HTTPS, SameSite contra el CSRF). Las sesiones: el estado se guarda del lado del SERVIDOR (el usuario no puede modificarlo), el navegador solo conserva un identificador de sesión. En PHP: session_start() al principio del script (antes de cualquier salida), luego almacenamiento y lectura vía $_SESSION ($_SESSION['user_id'] = 42;). Los datos sensibles viven en sesión — nunca en claro en una cookie. Riad lo aplica: idioma en cookie, identidad en sesión.
2. Una autenticación simple pero segura
Las sesiones sirven en particular a la autenticación. El ciclo: al CONECTARSE, se comprueban el identificador y la contraseña, luego se guarda la identidad en sesión ($_SESSION['user_id']); en cada página PROTEGIDA, se comprueba la sesión (si no, redirección a la conexión); al DESCONECTARSE, se destruye la sesión (session_destroy()). Tres protecciones no son negociables. Primero, las contraseñas se guardan con HASH con password_hash() y se comprueban con password_verify() — nunca en claro, nunca con un hash débil: una fuga de la base expondría si no todas las cuentas. Después, se regenera el identificador al conectarse (session_regenerate_id()) contra la fijación de sesión, con cookies de sesión seguras y HTTPS. Por último, se controlan los ACCESOS: comprobar no solo que el usuario está conectado (autenticación), sino que TIENE DERECHO a acceder al recurso (autorización) — si no, un miembro lee los datos de otro cambiando un id en la URL.
3. Las trampas que comprometen cuentas
La autenticación es un ámbito de alto riesgo: un error compromete cuentas reales. Trampas a desterrar: guardar una contraseña en claro; olvidar regenerar el ID de sesión; dejar las cookies de sesión sin HttpOnly/Secure/SameSite; trabajar sin HTTPS; comprobar la conexión pero no la autorización; revelar con mensajes de error demasiado precisos qué correos existen; no limitar los intentos (fuerza bruta); construir las consultas por concatenación en lugar de consultas preparadas (inyección SQL, nivel 3). Riad marcó cada punto antes de abrir el espacio de miembros. Y en un PROYECTO REAL, se privilegian los sistemas de autenticación PROBADOS de los frameworks, que gestionan correctamente estas sutilezas: comprender los mecanismos (como aquí) es esencial, implementarlos con rigor lo es aún más.
🔎 Ejemplo concreto — 🔎 Ejemplo concreto — La conexión de los miembros de Riad
Sesión + contraseña con hash, como en casa de Riad:
session_start();
if (password_verify($_POST['mdp'] ?? '', $user['hash'])) {
session_regenerate_id(true);
$_SESSION['user_id'] = (int) $user['id'];
}
// página protegida :
// if (!isset($_SESSION['user_id'])) { header('Location: connexion.php'); exit; }
Lectura: comprobación sobre el hash, ID regenerado contra la fijación, identidad del lado del servidor.
Lección: comprobar también la autorización (el DERECHO de acceso), no solo la conexión.
Vocabulario de la sección
- HTTP sin estado (stateless)
- Cada petición HTTP es independiente, el servidor no recuerda las anteriores; cookies y sesiones añaden una memoria entre páginas.
Ejemplo sencillo: Riad debe añadir una memoria para mantener conectados a sus miembros.
Lo que no es: un servidor que reconoce espontáneamente a sus visitantes.
Reflejo: estado entre páginas = cookie o sesión a prever.
- Cookies ($_COOKIE)
- Pequeños datos guardados en el NAVEGADOR, reenviados en cada petición (setcookie / $_COOKIE); lado del cliente por tanto modificables — opciones HttpOnly, Secure, SameSite.
Ejemplo sencillo: Riad memoriza el idioma elegido en una cookie.
Lo que no es: un almacenamiento seguro para la identidad o un rol.
Reflejo: cookie = solo preferencias no sensibles.
- Sesiones ($_SESSION)
- Estado guardado DEL LADO DEL SERVIDOR, no modificable por el usuario, el navegador solo guarda un identificador; session_start() y luego $_SESSION — el mecanismo seguro.
Ejemplo sencillo: La identidad de los miembros de Riad vive en $_SESSION['user_id'].
Lo que no es: un dato que el usuario puede editar en su navegador.
Reflejo: dato de confianza = sesión.
- Autenticación por sesión
- Conexión: comprobar identificador + contraseña y luego guardar la identidad en sesión; páginas protegidas: comprobar la sesión; desconexión: destruir la sesión.
Ejemplo sencillo: Riad protege el espacio de miembros con isset($_SESSION['user_id']).
Lo que no es: una página que confía en una cookie modificable.
Reflejo: cada página sensible = comprobación de sesión.
- Seguridad de sesión
- Contraseñas con HASH (password_hash/verify, nunca en claro), ID regenerado al conectarse, cookies seguras, HTTPS y control de accesos.
Ejemplo sencillo: Riad aplica hash en la inscripción y comprueba con password_verify.
Lo que no es: una contraseña guardada en claro o en md5.
Reflejo: nueva autenticación = lista de seguridad completa.
En la práctica — En la práctica — Gestionar el estado y una autenticación simple
- Inicie una sesión (session_start() al inicio del script, antes de cualquier salida) y guarde/lea datos vía $_SESSION.
- Cree una cookie con setcookie() (opciones HttpOnly/Secure) y léala vía $_COOKIE; comprenda que está guardada del lado del cliente (modificable).
- Construya una autenticación: al conectarse, compruebe la contraseña (password_verify sobre un hash), guarde $_SESSION['user_id'], regenere el ID de sesión.
- Proteja las páginas (comprobar la sesión, redirigir si no) y gestione la desconexión (session_destroy); recuerde: contraseñas con HASH, sesión protegida, HTTPS.
Script listo para decir — justificar la sesión ante el responsable asociativo (30 s)
«Para el espacio de miembros, la identidad vive en sesión, del lado del servidor: el miembro no puede modificarla. La cookie solo lleva el idioma. Las contraseñas tienen hash, nunca en claro, y regenero el identificador en cada conexión. Si alguien falsifica su cookie, no obtiene ningún acceso.»
Para decir mostrando una cookie modificada que no da ningún acceso; la demostración convence.
Modelo copiar-pegar — conexión y página protegida
' . htmlspecialchars('Identifiants invalides.', ENT_QUOTES, 'UTF-8') . '';
// --- página protegida (espace.php) ---
// session_start();
// if (!isset($_SESSION['user_id'])) { header('Location: connexion.php'); exit; }
// --- desconexión ---
// $_SESSION = []; session_destroy();
Preferencia de idioma
Riad memoriza el francés o el árabe en una cookie de larga duración: no sensible, perfecto para el cliente.
Cesta sensible
El contenido de la cesta de la tienda asociativa vive en sesión: el miembro no puede modificar los precios.
Desconexión limpia
Un clic vacía $_SESSION y destruye la sesión: en un ordenador compartido, ningún sucesor recupera la cuenta.
Hacia el framework
En un proyecto real, Riad confiará la autenticación al sistema probado del framework — mismos principios, sutilezas gestionadas.
✓ Buenas prácticas
- Usar las SESIONES para el estado sensible (identidad, cesta).
- Aplicar hash a las contraseñas con password_hash / password_verify, nunca en claro.
- Regenerar el ID de sesión al conectarse + cookies seguras + HTTPS.
✗ Errores frecuentes
- Guardar datos de confianza en una cookie (modificable por el usuario).
- Guardar una contraseña en claro o con md5/sha1.
- Comprobar solo la conexión y olvidar la autorización (acceso a datos ajenos).
Puntos clave
- HTTP es SIN ESTADO (cada petición independiente); COOKIES (lado del navegador, $_COOKIE) y SESIONES (lado del servidor, $_SESSION) añaden una «memoria» entre páginas.
- SESIONES = mecanismo SEGURO: datos del lado del servidor (no modificables), el navegador solo guarda un IDENTIFICADOR. Cookies = lado del cliente (modificables, para datos no sensibles).
- AUTENTICACIÓN: conexión (comprobar contraseña, guardar la identidad en sesión) → páginas protegidas (comprobar la sesión) → desconexión (destruir).
- SEGURIDAD (de alto riesgo): contraseñas con HASH (password_hash/verify, NUNCA en claro), regenerar el ID al conectarse, cookies seguras (HttpOnly/Secure/SameSite), HTTPS, control de accesos (autorización).
Reto 48h — aplique mañana
Construya una conexión mínima: un hash creado con password_hash, comprobación con password_verify, session_regenerate_id, almacenamiento de la identidad en sesión, una página protegida que redirige si no y una desconexión. Luego falsifique su cookie y constate que el acceso sigue denegado.
- Puedo explicar la diferencia cookie/sesión y decir dónde vive cada dato.
- Sé construir una conexión con hash, sesión regenerada y página protegida.
- He comprobado que una cookie falsificada no da ningún acceso.
Preguntas frecuentes
Cookies o sesiones: ¿qué diferencia hay y cuál usar para qué?
Ambas dan una «memoria» a HTTP, pero de forma distinta. COOKIES: datos en el NAVEGADOR (lado del cliente), reenviados en cada petición — VISIBLES y MODIFICABLES por el usuario, tamaño pequeño, posible persistencia larga; nunca datos sensibles en claro (opciones HttpOnly, Secure, SameSite). SESIONES: datos del lado del SERVIDOR, el navegador solo guarda un IDENTIFICADOR; el usuario NO PUEDE modificar los datos; mayor capacidad; dura generalmente la visita. Las sesiones usan una cookie (para el identificador) pero los DATOS quedan en el servidor — esa es la diferencia clave. Use las SESIONES para el estado SENSIBLE (autenticación, cesta) — la opción por defecto; las COOKIES para preferencias NO sensibles y persistencia larga (idioma, tema). Proteja ambas (opciones de cookie, regeneración de identificador, HTTPS).
¿Cómo construir una autenticación correcta y qué trampas evitar?
Pasos: (1) INSCRIPCIÓN — validar, aplicar HASH con password_hash(), guardar el HASH (nunca el claro). (2) CONEXIÓN — recuperar el usuario por correo (consulta PREPARADA), comprobar con password_verify(), luego session_regenerate_id() y guardar la identidad en sesión. (3) PÁGINAS PROTEGIDAS — comprobar la sesión (isset($_SESSION['user_id'])), si no redirigir. (4) AUTORIZACIÓN — comprobar el DERECHO sobre ESE recurso, no solo la conexión. (5) DESCONEXIÓN — vaciar y luego destruir la sesión. Trampas graves: contraseñas en CLARO o mal cifradas (lo peor), ID no regenerado (fijación), cookies no seguras, sin HTTPS, autorización olvidada, mensajes de error que revelan correos, intentos ilimitados (fuerza bruta), consultas concatenadas (inyección SQL). En un PROYECTO REAL, privilegie los sistemas de autenticación PROBADOS de los frameworks.
¿Dónde se guardan los datos de una SESIÓN?