Autenticación y Autorización en Apps con React Router y Hooks

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

Resumen

¿Cómo implementar un flujo de autenticación y autorización en aplicaciones?

En este emocionante recorrido, vamos a construir un flujo completo de navegación para aplicaciones que requieren autenticación y autorización utilizando React Router DOM. Aprenderemos a manejar rutas privadas y proteger contenido según el estado de autenticación del usuario.

¿Qué es la autenticación y autorización en aplicaciones web?

  • Autenticación: Es el proceso de verificar la identidad de un usuario. Un ejemplo común es el inicio de sesión en una aplicación.
  • Autorización: Es la verificación de los permisos que tiene un usuario autenticado para acceder a ciertos recursos o realizar acciones específicas.

En nuestro sistema, las rutas privadas estarán accesibles solo para usuarios autenticados, mientras que otras funcionalidades podrán variar dependiendo del rol del usuario.

¿Cómo simular la autenticación?

Hemos creado un sistema de autenticación ficticio para ilustrar cómo se podría implementar un flujo de autenticación. Inicialmente, esto se gestiona con React Hooks para simular un "login falso".

Pasos para crear la autenticación:

  1. Crear componentes de Login y Logout:

    • Desarrollar una estructura básica para las páginas de login y logout, replicando componentes de ejemplo, y aplicar la lógica de React Router para gestionar las rutas.
  2. Implementar un formulario de login:

    • Añadir un formulario que capture el nombre de usuario e integre un estado básico con useState para gestionar los cambios en el input.
import React, { useState } from 'react';

function LoginPage() {
  const [username, setUsername] = useState('');

  const handleLogin = (event) => {
    event.preventDefault();
    console.log(username); // Simulación de autenticación
  };

  return (
    <form onSubmit={handleLogin}>
      <label>Escribe tu nombre de usuario</label>
      <input 
        type="text" 
        value={username} 
        onChange={(e) => setUsername(e.target.value)} 
      />
      <button type="submit">Entrar</button>
    </form>
  );
}
  1. Crear un contexto para la autenticación:
    • Utilizar React.createContext para establecer un contexto que gestione el estado de autenticación y proporcionar funciones de login y logout.
import React, { createContext, useState, useContext } from 'react';

const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);

  const login = (username) => setUser({ username });
  const logout = () => setUser(null);

  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
};

export const useAuth = () => useContext(AuthContext);

¿Cómo integrar autenticación con rutas protegidas?

Una vez que se ha establecido un contexto para la autenticación, podemos utilizarlo para proteger rutas y condicionar la navegación según el estado de login del usuario.

Paso a paso:

  1. Utilizar el AuthProvider en tu aplicación:
    • Encapsular la estructura de la aplicación dentro del AuthProvider para que todas las rutas tengan acceso al contexto de autenticación.
import { AuthProvider } from './auth';

function App() {
  return (
    <AuthProvider>
      <HashRouter>
        {/* Rutas de tu aplicación */}
      </HashRouter>
    </AuthProvider>
  );
}
  1. Proteger rutas sensibles:
    • Condicionar el acceso a ciertas rutas verificando el estado de usuario en el contexto. Si no está autenticado, redirigir al login.
import { useAuth } from './auth';

function ProfilePage() {
  const auth = useAuth();

  if (!auth.user) {
    return <Redirect to="/login" />;
  }

  return <h1>Bienvenido, {auth.user.username}</h1>;
}

¿Cómo manejar la visibilidad de enlaces según el estado de autenticación?

Para mejorar la experiencia del usuario, es crucial ajustar la visibilidad de los enlaces de navegación según si el usuario está autenticado o no.

  1. Actualizar el menú de navegación:
    • Cambiar dinámicamente las opciones de navegación basándose en si el usuario ha iniciado sesión.
function Navigation() {
  const auth = useAuth();

  return (
    <nav>
      {!auth.user ? <Link to="/login">Login</Link> : <Link to="/logout">Logout</Link>}
      {auth.user && <Link to="/profile">Profile</Link>}
    </nav>
  );
}

Este enfoque garantiza que los usuarios no autenticados sean llevados a login si intentan acceder a áreas restringidas, y mantiene la interfaz limpia y adecuada a su estado. Este es solo el inicio de un sistema de autenticación robusto; las mejoras podrían incluir gestión de roles más compleja o integración con un backend para autenticación verificada. ¡Sigue explorando más sobre este tema para llevar tus proyectos al siguiente nivel!