Tradicionalmente, el sistema de tienda online PrestaShop, que funciona con PHP, no hacía uso de las sesiones de usuario, a pesar de ser algo que puede resultar realmente útil dentro de una aplicación web. Empezó a hacerlo en algún momento dentro de la rama 1.7, quizá cuando incorporó Symfony. Pero, en algunos aspectos, resulta demasiado tosco, porque se usa el manejador de sesiones de PHP sin más, sin ninguna personalización desde PrestaShop.
Uno de esos aspectos es el lugar donde se guardan las sesiones, esto es, la información de cada sesión de usuario. Es lo que se conoce en PHP como session save_path. Básicamente, es el directorio donde se guardará la información de cada sesión, en forma de archivo. Y PrestaShop utiliza el valor por defecto de la configuración de PHP en el servidor. Esto es algo que puede ser problemático.
Normalmente, el session save_path es un directorio que, en el caso de que haya varias webs en el mismo servidor, compartirán estas distintas webs. Esto abre la puerta a que se mezclen las sesiones de dos sitios web distintos. Sí, puede pasar si un mismo usuario visita desde su equipo esos dos sitios, porque además PrestaShop tampoco personaliza el nombre de sessión o session name.
Por otro lado, si hay problemas para escribir en el directorio de sesiones, se pueden producir errores en PrestaShop como una redirección infinita, que termina cortando el navegador por demasiadas redirecciones ("Too many redirects") en el backend, debido a que la seguridad se ha visto comprometida ("Security compromised").
Por todo ello, es muy recomendable personalizar en PrestaShop el directorio donde se guardarán los archivos de sesión. El manejo de sesiones se puede personalizar mucho en PHP, se puede incluso guardar las sesiones en base de datos en vez de en archivos. Pero, al menos, controlar el session save_path es algo básico que puede evitar problemas "raros" que a veces cuesta determinar su origen, porque como PrestaShop no usa las sesiones PHP para todo, entonces puedes ver la tienda funcionando aparentemente con normalidad, pero luego darte sorpresas.
No existe una opción dentro de PrestaShop para establecer este parámetro de configuración, pero se puede hacer de forma muy sencilla, desde código, sin alterar para nada el código fuente de PrestaShop ni comprometer futuras actualizaciones de versión de PrestaShop.
Lo primero de todo, tenemos que tener claro cuál queremos que sea el nuevo directorio donde PrestaShop guarde los archivos de sesión. Estas son dos buenas condiciones que debería cumplir ese directorio:
Con la primera condición, buscamos evitar usar un directorio compartido. Por ejemplo, si nuestra web es ejemplo.com, tenemos cPanel, y el usuario es ejemplo, querremos usar un directorio dentro de /home/ejemplo/, que es la carpeta de ese usuario. Y el directorio deberá tener ese mismo usuario y grupo ejemplo como propietarios, y permisos 0755. Si tenemos Plesk, la carpeta de ese usuario sería /var/www/vhosts/ejemplo.com/ y ahí es donde querríamos que esté el nuevo directorio para sesiones. En Plesk, normalmente el usuario propietario sería ejemplo y el grupo psacln.
Con la segunda condición, queremos evitar que los archivos de sesión puedan ser servidos y consultados vía web. Para esto, lo mejor es ubicar el directorio por encima del directorio raiz de la web. En cPanel, el directorio raiz de la web es public_html (dentro de la carpeta del usuario, comentada en el párrafo anterior), y en Plesk es httpdocs (también dentro de la carpeta del usuario).
Entonces, podemos crear un directorio llamado tmp directamente dentro de la carpeta del usuario (según el sistema), y confirmar que tiene los propietarios y permisos adecuados (comentados antes). Es posible que el directorio tmp ya exista. Podemos llamarlo sessions en vez de tmp, o, incluso mejor aún, crear un directorio sessions dentro de tmp.
Si no tuviésemos acceso por encima del raiz de la web, entonces crearíamos tmp/sessions dentro del mismo, pero crearíamos inmediatamente un archivo .htaccess con este contenido:
Deny from all
Eso evitará que ese directorio sea accesible vía web (siempre que el servidor soporte .htaccess).
Bien, tenemos ya preparado nuestro directorio para las sesiones, ahora vamos a decirle a PrestaShop que empiece a usarlo como tal. Para ello, utilizaremos la función de PHP session_save_path. Sí, vas a escribir un poquito de código, pero no te asustes, es sólo una línea ¡muy fácil!
Vamos a hacerlo de forma que no afecte negativamente a tu PrestaShop, sin tocar nada de su código fuente, y manteniendo la compatibilidad con futuras actualizaciones de PrestaShop. Simplemente, haremos uso del archivo de definiciones personalizadas. Ve al directorio config dentro del raiz de tu tienda PrestaShop. Comprueba si hay un archivo llamado defines_custom.inc.php, si no existe, créalo. Se trata de un archivo que, cuando existe, PrestaShop carga siempre al inicio de cada ejecución, por lo que nos viene genial para establecer constantes, parámetros de configuración, o cosas así. Edita el archivo, y simplemente escribe lo siguiente:
<?php
session_save_path(dirname(__FILE__) . '/../../tmp/sessions');
En ese ejemplo, le estamos indicando que el directorio de sesiones es tmp/sessions, un nivel por encima del raiz de la tienda.
Indica ahí el directorio que hayas decidido usar. Por ejemplo, para usar tmp/sessions dentro del raiz de la tienda, sería:
<?php
session_save_path(dirname(__FILE__) . '/../tmp/sessions');
Guarda el archivo y visita tu tienda, tanto el front como el backoffice. Luego, comprueba que efectivamente se están creando los archivos de sesión en el directorio elegido.
Ojo, si el archivo ya existiera y ya tuviese contenido, respétalo. Simplemente, añade la línea con la función session_save_path al final del archivo.
Recuerda que los permisos recomendados para config/defines_custom.inc.php son 0644.
Para definir el directorio de sesiones PHP a usar por tu tienda PrestaShop, simplemente edita el archivo config/defines_custom.php (créalo si no existe), y añade la instrucción:
session_save_path('ruta-al-directorio');
Por ejemplo:
session_save_path(dirname(__FILE__) . '/../../tmp/sessions');
Recuerda que al principio del archivo debe haber esta línea para indicar que es código PHP:
<?php
Es bastante fácil, espero no haberte liado dando demasiadas explicaciones.
Noticia siguiente: 20º Aniversario de mi relación con PHP
Noticia anterior: Programador PrestaShop