Las sesiones en PHP están controladas por varios parámetros que pueden trabajar juntos sin problemas o entrar en conflicto. Todos los ajustes de PHP mencionados a continuación pueden configurarse en php.ini
, en el vhost
(si se usa modPHP
de Apache) o en un archivo .htaccess
(si está permitido su uso).
Explicación general
Cuando cargamos (en un navegador) un sitio en PHP, el mecanismo por defecto del sitio es iniciar una "sesión", es decir, un pequeño espacio de almacenamiento de información sobre nosotros que podrá ser reutilizado en las siguientes páginas, lo que permite al servidor "recordarnos". Así, la siguiente página ya no necesita, por ejemplo, preguntarnos quiénes somos mediante un nombre de usuario y una contraseña. En el lado del servidor, estos valores se almacenan (generalmente en un archivo individual por sesión de usuario). Para que el servidor reconozca el navegador que consultó una página anterior, almacena en el navegador un número de sesión a través del mecanismo conocido como "cookie". Una cookie también es una forma de almacenar información en el navegador, pero por seguridad (confidencialidad de los datos), a menudo solo se almacenan información breve y no personal, como un... número de sesión.
La cookie se reutiliza para cualquier solicitud hacia el mismo sitio (URL): el navegador envía sistemáticamente la cookie cada vez que el usuario consulta cualquier otra página del sitio, y el servidor toma automáticamente en cuenta la cookie que tiene un nombre asignado para las cookies de sesión, encuentra el archivo correspondiente en el disco y lo carga en memoria antes de continuar la ejecución del código PHP.
Este mecanismo no solo existe en PHP, sino que cada lenguaje tiene la responsabilidad de gestionarlo a su manera.
En PHP, se pueden decidir variaciones del mecanismo de gestión de sesiones a través de opciones de configuración en el servidor. Por ejemplo, se puede decidir que las sesiones se almacenen en un servidor Redis (frecuentemente usado cuando se tienen varios servidores web para un mismo sitio y se desea que cualquier usuario tenga una experiencia unificada, sin importar en qué servidor se envíe su solicitud).
Por defecto, PHP almacena estas sesiones en un directorio (generalmente /var/lib/php/sessions, en Linux) y les asigna una duración de 24 minutos (o 1440 segundos, ya que los parámetros se almacenan en segundos).
Cada vez que se usa esta sesión (cada página cargada, por ejemplo), el contador se actualiza para que dure 24 minutos más.
En el lado del cliente, si no hay ninguna actividad (= carga de página, por ejemplo) durante 24 minutos, entonces la cookie (marcada inicialmente para una duración de 24 minutos) ya no es válida y el navegador ni siquiera la envía al servidor en una nueva solicitud, y se dice que "la sesión ha expirado". El sitio probablemente pedirá al usuario que se identifique nuevamente.
En el lado del servidor, es algo similar, y se hace como una medida de precaución: el servidor considera como expirados todos los archivos de sesión que no han sido "tocados" (consultados o modificados) en los últimos 24 minutos. Pero, y esto es muy importante para entender el mecanismo en su totalidad, los archivos correspondientes no se eliminan automáticamente después de 24 minutos. Dependerá del número de visitas al sitio y de la "probabilidad" de iniciar un mecanismo llamado el "garbage collector" (o "gc"), es decir, el "recolector de basura" de PHP, que es un proceso que se inicia o no en cada nueva visita al sitio. Son los siguientes parámetros los que decidirán este mecanismo.
Parámetros clave en el servidor
session.gc_probability
Define la probabilidad (expresada en porcentaje y en conjunto con session.gc_divisor
, ver más abajo) de que se ejecute la rutina de recolección de basura (gc
) en cada solicitud. El valor predeterminado es 1
.
session.gc_divisor
Trabaja junto con session.gc_probability
para definir la probabilidad de ejecución del gc
.
La probabilidad se calcula como gc_probability/gc_divisor
. Por ejemplo, 1/100
significa que hay un 1% de probabilidad de que se ejecute la rutina gc
en cada solicitud. El valor predeterminado es 100
.
session.gc_maxlifetime
Especifica el tiempo de vida de los datos de sesión en el servidor (en segundos). Después de este tiempo, los datos se consideran obsoletos y pueden ser eliminados por el recolector de basura.
Las sesiones pueden volverse obsoletas en el momento en que inician (según gc_probability
y gc_divisor
).
El valor predeterminado es 1440
segundos (24 minutos).
⚠️ Precaución: si varios scripts establecen diferentes valores de gc_maxlifetime
para la misma sesión de usuario, se tomará en cuenta el valor más bajo.
session.save_path
Define dónde se almacenan los archivos de sesión en el servidor.
Nota: Si se usa junto con un número de subdirectorios (por ejemplo, "2;/tmp"
), el recolector de basura predeterminado dejará de ejecutarse, por lo que las explicaciones anteriores sobre gc
ya no se aplicarán.
Parámetros clave en el cliente
session.cookie_lifetime
Especifica el tiempo de expiración de la cookie que identifica la sesión PHP.
Si se establece en 0
, la cookie expirará cuando se cierre la ventana o pestaña del navegador.
Recomendaciones
Idealmente, session.cookie_lifetime
y session.gc_maxlifetime
deberían tener el mismo valor, o gc_maxlifetime
debería establecerse en un valor específico si session.cookie_lifetime
está en 0
(porque, en ese caso, la sesión expirará al cerrar la pestaña, pero aún puede ser útil aplicar una medida de seguridad adicional en el servidor por si el usuario deja la pestaña abierta durante un largo período).
Riesgos de seguridad con cookies
Aunque este mecanismo ha funcionado bien durante décadas, todavía hay consideraciones importantes sobre su dependencia de las cookies:
- Las cookies pueden ser modificadas por el cliente. Dado que las cookies se almacenan en el navegador del usuario, pueden ser alteradas fácilmente. Por esta razón, los identificadores de sesión deben ser difíciles de adivinar (generalmente, son cadenas largas y aleatorias).
- Las cookies pueden ser leídas y modificadas por JavaScript. Un código malicioso (como ataques XSS o CSRF) podría acceder a las cookies y comprometer la seguridad del usuario. Algunos sitios implementan mecanismos de validación de cookies para evitar modificaciones no deseadas.
- Las cookies se envían con cada solicitud. Para evitar el "secuestro de sesión" (session hijacking), es fundamental usar conexiones HTTPS seguras. ⚠️ Nota: Muchos algoritmos antiguos de HTTPS ahora son inseguros, por lo que es importante actualizarlos periódicamente.
- Evitar almacenar demasiada información en cookies. Como las cookies se transmiten con cada solicitud, es preferible almacenar solo datos esenciales y mantener la información más pesada en el servidor para evitar una transferencia de datos innecesaria que pueda ralentizar el sitio.
¡Gracias por leer nuestro blog!
En BeezNest, además de nuestra especialización en el mundo del e-learning con software libre, somos expertos en tecnologías web. Si enfrentas desafíos técnicos complejos, podemos ofrecerte soluciones avanzadas en seguridad, optimización del rendimiento y carga de páginas de tu sitio. No dudes en 📧 [contactarnos] y dejar que nuestro equipo de expertos te ayude.