¿Qué se necesita para una buena experiencia de salida?

Kenji Baheux
Kenji Baheux

Cuando un usuario cierra sesión en un sitio web, comunica su necesidad de salir por completo de una experiencia del usuario personalizada. Por lo tanto, es importante adherirse lo más posible al modelo mental del usuario. Por ejemplo, una experiencia de cierre de sesión adecuada también debe tener en cuenta las pestañas que el usuario podría haber abierto antes de decidir cerrar la sesión.

La clave para una excelente experiencia de cierre de sesión se puede resumir en la coherencia en los aspectos visuales y de estado de la experiencia del usuario. En esta guía, se proporcionan consejos concretos sobre a qué prestar atención y cómo lograr una buena experiencia de cierre de sesión.

Consideraciones clave

Cuando implementes la función de cierre de sesión en tu sitio web, presta atención a los siguientes aspectos para garantizar un proceso de cierre de sesión fluido, seguro y, a la vez, intuitivo:

  • UX de cierre de sesión clara y coherente: Proporciona un botón o vínculo de cierre de sesión claro y visible de forma coherente que sea fácil de identificar y al que se pueda acceder en todo el sitio web. Evita usar etiquetas ambiguas o ocultar la función de cierre de sesión en menús, subpáginas o cualquier otra ubicación poco intuitiva.
  • Mensaje de confirmación: Implementa un mensaje de confirmación antes de finalizar el proceso de cierre de sesión. Esto puede ayudar a evitar que los usuarios salgan de su cuenta por accidente y les permite reconsiderar si realmente necesitan salir, por ejemplo, si bloquean diligentemente su dispositivo con una contraseña segura o algún otro mecanismo de autenticación.
  • Cómo controlar varias pestañas: Si un usuario abrió varias páginas del mismo sitio web en diferentes pestañas, asegúrate de que salir de la sesión en una pestaña actualice también todas las demás pestañas abiertas de ese sitio web.
  • Redirecciona a una página de destino segura: Después de cerrar sesión correctamente, redirecciona al usuario a una página de destino segura que indique claramente que ya no accedió a su cuenta. Evita redireccionar a los usuarios a páginas que tengan información personalizada. Del mismo modo, asegúrate de que las otras pestañas tampoco reflejen un estado de acceso. Además, asegúrate de no crear un redireccionamiento abierto del que los atacantes puedan aprovecharse.
  • Limpieza de la sesión: Una vez que un usuario cierra la sesión, se deben quitar por completo los datos sensibles de la sesión del usuario, las cookies o los archivos temporales asociados con la sesión del usuario. Esto evita el acceso no autorizado a la información del usuario o la actividad de la cuenta, y también impide que el navegador restablezca páginas con información sensible de sus diversas memorias caché, en particular la caché de atrás/adelante.
  • Administración de errores y comentarios: Proporciona mensajes de error o comentarios claros a los usuarios si hay problemas cuando cierran la sesión. Infórmales sobre cualquier riesgo de seguridad o filtración de datos potencial si falla el proceso de cierre de sesión.
  • Consideraciones de accesibilidad: Asegúrate de que el mecanismo de cierre de sesión sea accesible para los usuarios con discapacidades, incluidos aquellos que usan tecnologías de accesibilidad, como lectores de pantalla o navegación con el teclado.
  • Compatibilidad con varios navegadores: Prueba la función de cierre de sesión en diferentes navegadores y dispositivos para asegurarte de que funcione de manera coherente y confiable.
  • Supervisión y actualizaciones continuas: Supervisa periódicamente el proceso de cierre de sesión para detectar posibles vulnerabilidades o brechas de seguridad. Implementa actualizaciones y parches oportunos para abordar los problemas identificados.
  • Federación de identidades: Si el usuario accedió con una identidad federada, verifica si también se admite y es necesario salir del proveedor de identidad. Además, si el proveedor de identidad admite el acceso automático, no olvides impedirlo.

Qué hacer

  • Si invalidas una cookie en el servidor como parte de un flujo de cierre de sesión (o de otros flujos de revocación de acceso), asegúrate de borrar la cookie también en el dispositivo del usuario.
  • Borra los datos sensibles que hayas almacenado en el dispositivo del usuario: cookies, localStorage, sessionStorage, indexedDB, CacheStorage y cualquier otro almacén de datos local.
  • Asegúrate de que todos los recursos que contengan datos sensibles, en particular los documentos HTML, se muestren con el encabezado HTTP Cache-control: no-store para que el navegador no los almacene en el almacenamiento permanente (por ejemplo, en el disco). Del mismo modo, las llamadas a XHR o fetch que devuelven datos sensibles también deben establecer el encabezado HTTP Cache-Control: no-store para evitar el almacenamiento en caché.
  • Asegúrate de que todas las pestañas abiertas en el dispositivo del usuario estén actualizadas con las revocaciones de acceso del servidor.

Limpieza de datos sensibles al salir de la cuenta

Cuando salgas de la cuenta, considera borrar los datos sensibles efímeros y almacenados localmente. El enfoque en los datos sensibles se debe a que borrar todo generaría una experiencia del usuario significativamente peor, ya que es muy probable que este usuario regrese. Por ejemplo, si borraras todos los datos almacenados de forma local, tus usuarios deberán volver a confirmar los mensajes de consentimiento de cookies y realizar otros procesos como si nunca hubieran visitado tu sitio web.

Cómo limpiar las cookies

En la respuesta de la página que confirma el estado de cierre de sesión, adjunta encabezados HTTP Set-Cookie para borrar todas las cookies relacionadas con datos sensibles o que los contengan. Establece el valor de expires en una fecha muy anterior y, para mayor seguridad, establece el valor de la cookie en una cadena vacía.

Set-Cookie: sensitivecookie1=; expires=Thu, 01 Jan 1970 00:00:00 GMT; secure
Set-Cookie: sensitivecookie2=; expires=Thu, 01 Jan 1970 00:00:00 GMT; secure
...

Situación sin conexión

Si bien el enfoque descrito anteriormente es suficiente para los casos de uso generales, no funciona si el usuario trabaja sin conexión. Te recomendamos que consideres solicitar dos cookies para hacer un seguimiento del estado de acceso: una cookie segura de solo HTTPS y una cookie normal a la que se pueda acceder a través de JavaScript. Si el usuario intenta salir de su cuenta sin conexión, puedes borrar la cookie de JavaScript y continuar con otras operaciones de limpieza si es posible. Si tienes un service worker, también puedes aprovechar la API de Background Fetch para reintentar una solicitud para borrar el estado en el servidor cuando el usuario esté en línea más tarde.

Cómo liberar espacio de almacenamiento

En la respuesta de la página que confirma el estado de cierre de sesión, asegúrate de limpiar los datos sensibles de varios almacenes de datos:

  • sessionStorage: Si bien se borra cuando el usuario finaliza su sesión en tu sitio web, considera borrar de forma proactiva los datos sensibles cuando el usuario salga de su cuenta, en caso de que olvide cerrar todas las pestañas abiertas en tu sitio web.

    // Remove sensitive data from sessionStorage
    sessionStorage.removeItem('sensitiveSessionData1');
    // ...
    
    // Or if everything in sessionStorage is sensitive, clear it all
    sessionStorage.clear();
    
  • APIs de localStorage, indexedDB, Cache o Service Worker: Cuando el usuario cierra la sesión, borra cualquier dato sensible que hayas almacenado con estas APIs, ya que esos datos persistirían entre sesiones.

    // Remove sensitive data from localStorage:
    localStorage.removeItem('sensitiveData1');
    // ...
    
    // Or if everything in localStorage is sensitive, clear it all:
    localStorage.clear();
    
    // Delete sensitive object stores in indexedDB:
    const name = 'exampleDB';
    const version = 1;
    const request = indexedDB.open(name, version);
    
    request.onsuccess = (event) => {
      const db = request.result;
      db.deleteObjectStore('sensitiveStore1');
      db.deleteObjectStore('sensitiveStore2');
    
      // ...
    
      db.close();
    }
    
    // Delete sensitive resources stored with the Cache API:
    caches.open('cacheV1').then((cache) => {
      await cache.delete("/personal/profile.png");
    
      // ...
    }
    
    // Or better yet, clear a cache bucket that contains sensitive resources:
    caches.delete('personalizedV1');
    

Cómo limpiar las cachés

  • Caché HTTP: Siempre y cuando establezcas Cache-control: no-store en los recursos con datos sensibles, la caché HTTP no conservará nada que sea sensible.
  • Caché de atrás/adelante: Del mismo modo, si seguiste las recomendaciones sobre Cache-control: no-store y sobre borrar las cookies sensibles (por ejemplo, las cookies seguras solo para HTTPS relacionadas con la autenticación) cuando los usuarios cierran la sesión, no tienes que preocuparte por que se retengan datos sensibles en la caché de atrás/adelante. De hecho, la función de caché atrás/adelante desalojará las páginas del mismo origen que se publiquen con un encabezado HTTP Cache-control: no-store si observa uno o más de los siguientes indicadores:
    • Se modificaron o borraron una o más cookies seguras de solo HTTPS.
    • Una o más respuestas para las llamadas de XHR/fetch (emitidas por la página) incluyeron el encabezado HTTP Cache-control: no-store.

Experiencia del usuario coherente en todas las pestañas

Es posible que los usuarios hayan abierto muchas pestañas de tu sitio web antes de decidir salir de su cuenta. Para entonces, es posible que haya olvidado otras pestañas o incluso otras ventanas del navegador. Es mejor evitar que los usuarios cierren todas las pestañas y ventanas pertinentes. En cambio, adopta una postura proactiva y asegúrate de que el estado de acceso del usuario sea coherente en todas las pestañas.

Instructivo

Para lograr un estado de acceso coherente en todas las pestañas, considera usar una combinación de eventos pageshow/pagehide y la API de Broadcast Channel.

  • Evento pageshow: Cuando se conserve un pageshow, verifica el estado de acceso del usuario y borra los datos sensibles (o incluso toda la página) si el usuario ya no accedió a su cuenta. El evento pageshow se activará antes de que se renderice la página por primera vez cuando se restablezca desde una navegación atrás/adelante, de modo que la verificación del estado de acceso te permita restablecer la página a un estado no sensible.

    window.addEventListener('pageshow', (event) => {
      if (event.persisted && !document.cookie.match(/my-cookie)) {
        // The user has logged out.
        // Force a reload, or otherwise clear sensitive information right away.
        body.innerHTML = '';
        location.reload();
      }
    });
    
  • API de Broadcast Channel: Usa esta API para comunicar los cambios de estado de acceso en pestañas y ventanas. Si el usuario salió de su cuenta, borra todos los datos sensibles o, como alternativa, redirecciona a una página de salida en todas las pestañas y ventanas con datos sensibles.

    // Upon logout, broadcast new login state so that other tabs can clean up too:
    const bc = new BroadcastChannel('login-state');
    bc.postMessage('logged out');
    
    // [...]
    const bc = new BroadcastChannel('login-state');
    bc.onMessage = (msgevt) => {
      if (msgevt.data === 'logged out') {
        // Clean up, reload or navigate to the sign-out page.
        // ...
      }
    }
    

Conclusión

Si sigues las instrucciones de este documento, podrás diseñar una excelente experiencia del usuario para el cierre de sesión que evite los cierres de sesión no deseados y proteja la información personal del usuario.