Una sesión que desaparece parece un problema de acceso y casi nunca lo es. El acceso funcionó; lo que se perdió fue la prueba de ese acceso, entre una petición y la siguiente.
1. Algo está limpiando los archivos de sesión
En Debian y Ubuntu, un temporizador barre los archivos de sesión de PHP según su propio calendario, usando la idea que tiene la DISTRIBUCIÓN de la duración, no la que su página fija con ini_set. Una página que sube gc_maxlifetime en tiempo de ejecución no cambia nada de ese barrido.
systemctl list-timers | grep phpsessionclean
php -i | grep -E "session.save_path|session.gc_maxlifetime"
El remedio es un directorio de sesiones propio que el barredor no toca, con su duración fijada en la configuración del pool y no en tiempo de ejecución.
php_admin_value[session.save_path] = /var/lib/php/sessions-mysite
php_admin_value[session.gc_maxlifetime] = 86400
2. La cookie no vuelve
session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = Lax
3. Dos servidores, una sesión
Detrás de un balanceador, la primera petición cae en el servidor A y escribe allí un archivo de sesión; la segunda cae en B, que no tiene ese archivo. El usuario se desconecta al azar, que es la versión más difícil de reproducir.
- Sesiones en Redis o en la base de datos, compartidas por los dos.
- O sesiones pegajosas en el balanceador: funciona, y no sobrevive a que se reemplace un servidor.
Véalo ocurrir
ls -la /var/lib/php/sessions/ | head
# log in, then look again: your file should be there and should stay