Este sistema es para una aplicación web de carga y uso compartido de archivos personales hecha con PHP.
Cuando un usuario inicia sesión en la aplicación, tiene la opción de "permanecer conectado" después de cerrar y volver a abrir su navegador, al igual que la mayoría de las aplicaciones web. Lo que esto hace en realidad es que establece una cookie HTTP, llamada auth
, con un vencimiento de 90 días en el navegador del cliente que contiene una cadena en el siguiente formato: UserIdentifier:SeriesNumber:Token
donde :
es el delimitador. Los mismos datos también se conservan en la tabla de base de datos user_auths
, pero el token se procesará antes de que sea.
El UserIdentifier
es el identificador de usuario del usuario que optó por permanecer conectado, el SeriesNumber
es un número aleatorio generado entre 0 y 2147483647 (inclusive) y el Token
una cadena de caracteres aleatoria generada de 60 caracteres alfabéticos , caracteres numéricos y simbólicos. Un valor de ejemplo sería: 1:902449381:j7j]fP%CxIzcKSg/'wG]XzJd.OsX8"K0FlY')xXQz.5.Q]+KJnXi<>p/t7nz
Cada vez que un usuario visite la aplicación y no se encuentre en la sesión HTTP, lo haré:
-
Intente encontrar la cookie
auth
en el navegador del cliente. Si se encuentra, verifico si su valor contiene dos:
delimitadores (verificando el formato correcto), si no se encuentra la cantidad correcta de delimitadores, elimino la cookie del navegador del cliente y el usuario está no autenticado. -
Si se pasa la prueba anterior, usaré el identificador de usuario para buscar en la tabla db si el usuario del identificador dado tiene cualquiera filas en la tabla (lo que significa que el usuario < em> ha optado por "permanecer conectado" en uno o más navegadores). Si el identificador de usuario no se encuentra en la tabla, elimino la cookie del navegador del cliente y el usuario no está autenticado.
-
Si se pasa la prueba anterior, ahora usaré el número de serie y del identificador de usuario para verificar si hay una fila coincidente en la tabla de la base de datos. Si se encuentra, verifico el token de texto claro de la cookie con el token hash de la fila correspondiente. Si no se encuentra o no se verifica el token, asumo que o bien se produjo un robo de cookie O el valor de la cookie se ha manipulado. Yo invalido / elimino TODOS los datos de persistencia de autenticación de este usuario para que no se "mantenga conectado" en el navegador CUALQUIERA que optó, y es no autenticado.
-
Si la cookie ha pasado la prueba anterior, significa que la cookie y sus datos eran válidos y que el usuario se considera autenticado. Regenero el identificador de sesión y pongo al usuario en la sesión. Genero un token nuevo , un hash, lo actualizo en la fila de la tabla correspondiente y emito al navegador del usuario una nueva cookie
auth
con el mismo identificador de usuario, número de serie y fecha de caducidad, pero con el nuevo token ( versión en texto claro).
Todo esto se procesa por en cada solicitud. Para cada navegador el proceso es idéntico. Un usuario puede optar por "permanecer conectado" en los múltiples navegadores que quiera y también tendrá la opción de invalidar todos los inicios de sesión persistentes de su cuenta.
Para finalizar, tengo un script que comprueba la tabla db cada N minutos para las filas más antiguas luego de 90 días y las elimina para mantener la tabla limpia e invalidar los inicios de sesión persistentes después de la fecha de caducidad .