Problemas de deslogueo en NextAuth.js a través de múltiples pestañas del navegador

En este artículo, abordaremos un problema común que enfrentan los desarrolladores que utilizan NextAuth.js para la autenticación en aplicaciones de Next.js: la dificultad para cerrar sesión de manera efectiva en múltiples pestañas del navegador.

Problema

  1. Deslogueo: Al cerrar sesión en una pestaña, la sesión no se borra en otras pestañas abiertas del mismo navegador.
  2. Al actualizar manualmente las otras pestañas después de cerrar sesión, éstas continúan mostrando al usuario como conectado.
  3. Al iniciar sesión, abrir una nueva pestaña mantiene al usuario conectado automáticamente, lo cual es el comportamiento esperado.
  4. El cierre de sesión funciona correctamente en una sola pestaña.

Código utilizado para cerrar sesión

Se utiliza la función signOut() de next-auth/react para gestionar el cierre de sesión:

const handleClose = async (type="") => {  
   setAnchorEl(null); 
   if (type === 'logout') {      
      localStorage.setItem("nextauth_logout", Date.now().toString());   
      await signOut({ redirect: false });  
   } 
};

Solución intentada

Se creó un hook personalizado para escuchar los cambios de cierre de sesión en otras pestañas, sin embargo, incluso al activar este hook, la sesión permanece activa en la pestaña desde la que se cerró la sesión:

const useMultiTabLogout = () => {
  useEffect(() => {
    const handleStorageChange = (event) => {
      if (event.key === "nextauth_logout" && event.newValue) {
        signOut();
      }
    };

    window.addEventListener("storage", handleStorageChange);
    return () => window.removeEventListener("storage", handleStorageChange);
  }, []);
};

Solución Propuesta

Para resolver el problema de cerrar sesión correctamente en múltiples pestañas, se sugiere implementar lo siguiente:

  1. Uso de localStorage: Al cerrar sesión, actualiza localStorage para notificar a las otras pestañas que deben actualizar su estado de sesión.
  2. Escuchador de eventos: Asegúrate de que el escuchador de eventos está correctamente configurado para que signOut() se ejecute cada vez que se detecte un cambio en el localStorage.

Aquí tienes un ejemplo de cómo podrías implementar esto:

const handleClose = async (type="") => {  
   setAnchorEl(null); 
   if (type === 'logout') {      
      localStorage.setItem("nextauth_logout", Date.now().toString());   
      await signOut({ redirect: false });  
   } 
};

const useMultiTabLogout = () => {
  useEffect(() => {
    const handleStorageChange = (event) => {
      if (event.key === "nextauth_logout") {
        signOut();
      }
    };

    window.addEventListener("storage", handleStorageChange);
    return () => window.removeEventListener("storage", handleStorageChange);
  }, []);
};

Conclusión

El uso de NextAuth.js para la autenticación en una aplicación Next.js puede llevar a ciertos desafíos, especialmente al manejar el estado de sesión en varias pestañas del navegador. A través de un manejo adecuado de los eventos de localStorage, es posible garantizar que el cierre de sesión funcione de manera efectiva en todas las pestañas abiertas, mejorando así la experiencia del usuario. Implementar y ajustar adecuadamente este enfoque permitirá resolver los problemas de sesión en su aplicación.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *