Control de Acceso en Menú con Autenticación React

Clase 12 de 30Curso de React.js: Navegación con React Router

Contenido del curso

Fake authentication con React Router DOM 6

React Router en TODO Machine

Resumen

Controlar qué enlaces aparecen en el menú según el estado de autenticación es una necesidad real en cualquier aplicación con React. Aquí se aborda paso a paso cómo mostrar u ocultar rutas en función de si el usuario ya hizo login o no, utilizando React Context, hooks personalizados y propiedades condicionales en cada ruta.

¿Por qué el menú debe reaccionar al estado de autenticación?

Cuando un usuario no ha iniciado sesión, mostrarle un enlace a "Profile" provoca un error. El contexto de autenticación no tiene la propiedad username, React no la encuentra y la aplicación se rompe [0:42]. Lo mismo ocurre a la inversa: si ya existe una sesión activa, no tiene sentido seguir mostrando la página de login en el menú.

El objetivo es claro:

  • Usuario sin sesión: mostrar solo rutas públicas como login.
  • Usuario con sesión: mostrar rutas privadas como profile y logout, y ocultar login.

¿Cómo se agregan propiedades de visibilidad a las rutas?

Dentro del archivo del menú, cada ruta ya es un objeto con sus propiedades básicas. La estrategia consiste en añadir una nueva propiedad llamada private [2:06].

js // Ejemplo de rutas con la propiedad private const routes = [ { path: '/home', label: 'Home', private: false }, { path: '/login', label: 'Login', private: false }, { path: '/profile', label: 'Profile', private: true }, { path: '/logout', label: 'Logout', private: true }, ];

Por defecto, todas las rutas tienen private: false, es decir, son públicas. Solo profile y logout se marcan como private: true.

¿Cómo accede el menú al estado de autenticación?

Para que el menú sepa si el usuario está autenticado, se importa el hook personalizado useAuth [2:52]. Este hook devuelve un objeto auth donde auth.user contiene la información del usuario o null si no hay sesión.

Un detalle importante: el componente del menú debe estar dentro del AuthProvider y del HashRouter [3:26]. Si no está envuelto por estos proveedores, no podrá usar ni useAuth ni componentes de navegación como NavLink o useNavigate.

¿Cuál es el condicional para ocultar rutas privadas?

Dentro del routes.map, en lugar de hacer un return implícito, se agregan llaves para incluir validaciones antes de renderizar [3:50]:

js routes.map(route => { if (route.private && !auth.user) { return null; } return ( // renderizar el enlace normalmente ); });

Si la ruta es privada y no existe auth.user, se devuelve null y el enlace no aparece en el menú [4:28]. Si el condicional no se cumple, significa que la ruta es pública o que el usuario ya está autenticado, así que se renderiza con normalidad.

¿Cómo ocultar rutas públicas cuando ya hay sesión activa?

Aquí viene la segunda parte del problema. Tras hacer login, la página de login sigue visible en el menú [5:27]. Para resolverlo se introduce una nueva propiedad: publicOnly.

js { path: '/login', label: 'Login', private: false, publicOnly: true },

El condicional adicional queda así [6:22]:

js if (route.publicOnly && auth.user) { return null; }

Si la ruta tiene publicOnly: true y el usuario ya tiene sesión, el enlace desaparece del menú. De esta forma, login solo se muestra cuando no hay autenticación.

El resultado final del flujo completo [6:48]:

  • Sin sesión: aparece login, no aparecen profile ni logout.
  • Con sesión: aparecen profile y logout, no aparece login.

¿Por qué preguntar cuándo NO renderizar en vez de cuándo sí?

La clave de esta implementación es pensar al revés [7:18]. En lugar de construir un condicional largo que cubra todos los escenarios para renderizar, se pregunta únicamente cuáles son las condiciones para NO renderizar. Si alguna se cumple, se devuelve null. Si ninguna aplica, se renderiza normalmente. Esto produce un código más limpio y legible.

Aún queda un problema por resolver: si el usuario cambia la URL manualmente, puede acceder a rutas que deberían estar protegidas o que ya no corresponden a su estado de sesión [8:06]. Proteger el menú no es suficiente; también hay que proteger las rutas a nivel de navegación con redirects. ¿Cómo lo resolverías tú? Comparte tu enfoque en los comentarios.

      Control de Acceso en Menú con Autenticación React