Ayer me surgió un problemilla relacionado con sesiones y cookies, y algún pequeño misterio (aún) sin resolver. A ver si consigo explicar un poco el tema de las cookies y las sesiones para mi yo del futuro, y a ver también si alguien me puede dar una pista acerca del misterio.
1. Sesiones
Una sesión es una forma de mantener el estado utilizando un protocolo como HTTP que, por construcción, no está pensado para mantener el estado. Normalmente, una sesión dura desde que el usuario abre el navegador hasta que lo cierra. El servidor web puede pasar información entre diferentes páginas durante la misma sesión. Cuando el navegador solicita la página (esa que va a trabajar con sesiones), el servidor web le asigna un identificador de sesión (SESSID), se lo envía al cliente y le pide que lo guarde "en algún sitio" (normalmente, en una cookie). Después, cada vez que el usuario haga una petición de página, el servidor web recibirá ese SESSID en una cookie (eso es lo habitual, aunque también puede enviarse en la propia URL de acceso). Conservando cierta información ligada al identificador de la sesión (en el servidor web), puede darse un servicio personalizado al usuario, como mantener un carrito de la compra, por ejemplo. Para mantener esta información, el desarrollador web puede almacenar determinadas variables (nombre:valor) en la sesión.
El servidor web guardará la información de la sesión en algún sitio, puede ser en ficheros de texto, binarios, en una base de datos... Normalmente, una configuración por defecto de Apache + PHP implica que se guarden en ficheros de texto plano.
Vale. Hasta aquí bien.
2. Cookies
Para guardar en el navegador del cliente el ID de sesión se utilizan cookies habitualmente. El servidor web le pide al navegador del usuario: "Anda, porfa, ¿puedes guardar por ahí en algún sitio que la variable <loquesea> almacene el valor <patatín-patatán>? Más adelante, cuando vuelvas, yo te pediré si tienes esta información guardada y, si la tienes, te reconoceré y sabré que eres tú, mi amor" (sí, los servidores web son así de ligones con los navegadores).
Los servidores pueden usar así esta información para "recordar" las preferencias del usuario, su login automático y un sinfín de cosas más útiles y beneficiosas para el usuario, y algunas otras que no son tan beneficiosas para el usuario (pero sí para ciertos sitios web, especialmente si venden publicidad o si tienen intenciones algo más siniestras), por ejemplo, para rastrear las preferencias y hábitos de navegación.
Los navegadores o, lo que es lo mismo, los usuarios, sabemos que si nos hacemos los estrechos la página no nos va a dar mucha funcionalidad, así que nos ponemos en modo facilón, nos dejamos querer y accedemos fácilmente a que el servidor web nos
penetr meta esos datos sin excesivos reparos. (¿Cuántas veces has "Entendido" que un sitio web utiliza cookies y has consentido? Luego no vayamos con excusas, que así pasa lo que pasa).
El navegador guarda ese paquetito de información, esa cookie, en un fichero pequeño normalmente de texto (también pueden ser binarios) o, algo que se ve cada vez más en las últimas versiones de los navegadores, en bases de datos locales tipo SQLite o similares. En cualquier caso, ficheros en el ordenador del cliente web. O, al menos esto es así en teoría, ya que aquí me surge el primer misterio que mencionaba en la introducción. Pero antes de abordar el misterio, recapitulemos lo que llevamos dicho hasta ahora.
Resumiendo:
-
Cookies: pequeños trozos de información que almacena el navegador en ficheros de texto, binarios o BD locales tipo SQLite. Se pueden usar para muchas cosas, una de ellas para almacenar ID de sesión (pero también para rastrear al usuario, conocer preferencias...)
-
Sesiones: interacciones entre navegador y servidor web que recuerdan info (estado) del usuario, normalmente usando cookies. La información se almacena en el servidor, ya sea en ficheros de texto (pares nombre:valor), binarios, bases de datos...
3. Vale. ¿Y dónde se almacenan?
3.1 LAS COOKIES
Pues... depende del navegador. En el caso de Firefox, el directorio es el del perfil del usuario, como explican aquí
https://support.mozilla.org/es/kb/perfiles-el-lugar-donde-firefox-almacena-tus-contr
que se encuentra dentro de la carpeta %AppData%\Roaming\Mozilla\Firefox\Profiles
Si sólo tienes un perfil de usuario, éste incluye la palabra 'default' en el nombre de la carpeta. En mi caso:
%AppData%\Roaming\Mozilla\Firefox\Profiles\67bl3kpn.default-1443683694326
y, dentro de esta carpeta, hay un archivo cookies.sqlite
Fig. 1. Archivo SQLite de cookies en Firefox
El contenido de este archivo se puede ver con cualquier visualizador de ficheros SQLite. A mí me gusta mucho el SQLite Expert (edición Personal). Más adelante le echaremos un vistazo.
En el caso de Chrome, la ruta donde se almacena la BD de cookies es
%LOCALAPPDATA%\Google\Chrome\User Data\Default\Cookies
y el fichero se llama cookies a secas, sin extensión. También lo podemos abrir con SQLite Expert o cualquier otro visor.
Si echamos un vistazo a ambos ficheros, veremos cosas parecidas a esto en el caso de Firefox
Fig.2. Fichero de cookies en Firefox 47.0
y esto en el caso de Chrome
Fig.3. Fichero de cookies en Chrome
3.2 LAS SESIONES
La información de la sesión se almacena, como hemos dicho, en el servidor web. En el caso de Apache con PHP, que es el servidor que yo voy a utilizar en este caso, la ubicación de las variables de sesión se almacenan en el directorio que se especifique en php.ini, en el parámetro session.save_path. En mi caso, utilizando un paquete XAMPP integrado, la ruta es C:\xampp\tmp.
Fig.4. Configuración de la ruta donde guardar las sesiones
Si miramos en esa carpeta, veremos las sesiones que se han ido creando en los últimos días:
Fig.5. Contenido de la carpeta de almacenamiento de sesiones
4. ¿Me puedes poner un ejemplo?
Sí, será lo mejor. Todo esto puede ser un poco confuso, y la mejor forma de verlo claro es con un ejemplo. Haremos dos páginas PHP que se pasarán información de una a otra utilizando una sesión de usuario, e iremos viendo dónde, cómo y con qué contenido se van creando los ficheros.
Página 1
01 <?php
02 session_start();
03 ?>
04 <!DOCTYPE html>
05 <html lang="es">
06
07 <head>
08 <meta charset="utf-8" />
09 <title>Sesiones - Página 1</title>
10 </head>
11
12 <body>
13 <?php
14 echo 'Estamos en la sesión [' . session_id() . ']<br />'
15 . 'Nombre: ' . session_name() . '<br />';
16
17 //almacenamos algún dato en esa sesión
18 $_SESSION['mes'] = 'junio';
19 $_SESSION['usuario'] = 'pepe';
20 $_SESSION['flor'] = 'amapola';
21
22 echo '<pre>';
23 print_r($_SESSION);
24 echo '</pre>';
25 echo "<br>Ir a <a href='pagina2.php'>la página 2</a> a consultar las variables de sesión"
26
27 ?>
28
29 </body>
30 </html>
Y esta es la página 2
01 <?php
02 session_start();
03 ?>
04 <!DOCTYPE html>
05 <html lang="es">
06
07 <head>
08 <meta charset="utf-8" />
09 <title>Sesiones</title>
10 </head>
11
12 <body>
13 <?php
14 echo 'Estamos en la sesión [' . session_id() . ']<br />Nombre: ' . session_name() . '<br />';
15
16 //recuperamos los valores almacenados en la sesión
17 echo 'Recuperamos el valor mes=' . $_SESSION['mes'] . '<br />';
18 echo 'Recuperamos el valor usuario=' . $_SESSION['usuario'] . '<br />';
19 echo 'Recuperamos el valor flor=' . $_SESSION['flor'] . '<br />';
20
21 echo '<pre>';
22 print_r($_SESSION);
23 echo '</pre>';
24 ?>
25 </body>
26 </html>
Abramos en el navegador la página 1
Fig. 6. Página 1, creando la sesión y almacenando algunas variables en ella.
Antes de pasar a la página 2, veamos qué ha pasado en los sistemas de archivos del servidor y del cliente.
En el servidor
Fig. 7. Fichero de sesión en el sistema de archivos del servidor web
como se ve, el nombre del archivo coincide con el session_id que hemos visto en la página. Si abrimos ese fichero, su contenido es:
Fig. 8. Contenido del fichero de sesión con las variables de la misma
Hmmm... Interesante. Vemos que junto a cada variable aparece un tipo de datos (s=string), su tamaño (5) y su valor ("junio"). Las distintas variables de sesión se separan con pipelines.
Pero es a la hora de ver qué ha pasado con las cookies en el cliente cuando aparece el primer "misterio". En teoría, las cookies se almacenan en la BD SQLite que hemos dicho. Pero, cuando muestro las cookies ordenadas por fecha de acceso, no encuentro la cookie de nombre PHPSESSID, que es el nombre que me devuelve la función session_name(). Esto es lo que consigo ver cuando accedo a la BD y filtro por el dominio 'localhost':
Fig. 9. Contenido del fichero de cookies para el dominio 'localhost' en Firefox.
¿Y la cookie PHPSESSID?
Como tras muchos intentos no he conseguido encontrar esta información en la BD, al final he instalado el plugin Firebug en Firefox, que permite visualizar las cookies y ahí sí que puedo ver la cookie que me interesa, como se puede ver un poco más arriba en la figura 6. También si abro la página 2 con el Firebug activado (F12) puedo ver que la cookie de sesión PHPSESSID es la misma
Fig. 10. Página 2 mostrando la cookie de sesión y las variables asociadas, junto a sus valores
Aún no he conseguido averiguar dónde se almacena la cookie PHPSESSID, pero es obvio que el navegador la está guardando en algún sitio y a mí me gustaría saber dónde. Vale que con el Firebug puedo inspeccionar la cookie, lo cual me soluciona la papeleta por el momento, pero me quedo un poco mosca con no haber podido encontrar la ubicación exacta de la cookie en el disco.
¿Alguien tiene alguna idea?