Simular un sistema de autenticación con JWT (JSON ...
Creado el: 22 de marzo de 2025
Creado el: 22 de marzo de 2025
Simular un sistema de autenticación con JWT (JSON Web Tokens). Utilizar Zustand para manejar el estado de autenticación y Axios para enviar solicitudes a una API simulada.
Características:
Configura un store de Zustand para gestionar el estado de autenticación (ej: isAuthenticated, userData, token).
Simula el proceso de inicio de sesión:
Envía credenciales (usuario/contraseña) a una API simulada usando Axios.
Recibe un JWT simulado y guárdalo en el store.
Implementa la validación del token para mantener la sesión activa.
Asegúrate de que el token persista en el localStorage para mantener la sesión tras recargar la página.
Entregable:
Código del sistema de autenticación con Zustand y Axios.
Un ejemplo práctico de uso (ej: proteger rutas o mostrar contenido según el estado de autenticación).
A continuación, te proporciono un ejemplo de un sistema de autenticación utilizando Zustand y Axios con JWT. Este ejemplo simula el proceso de inicio de sesión, la validación del token y el almacenamiento del token en localStorage
para persistir la sesión tras recargar la página.
Primero, necesitamos configurar un store de Zustand para manejar el estado de la autenticación.
javascript// authStore.js import create from 'zustand'; const useAuthStore = create((set) => ({ isAuthenticated: false, userData: null, token: localStorage.getItem('authToken') || null, login: (token, userData) => { localStorage.setItem('authToken', token); // Guarda el token en localStorage set({ isAuthenticated: true, userData, token, }); }, logout: () => { localStorage.removeItem('authToken'); // Elimina el token del localStorage set({ isAuthenticated: false, userData: null, token: null, }); }, setToken: (token) => set({ token }), setUserData: (data) => set({ userData: data }), })); export default useAuthStore;
Este store de Zustand tiene un estado que contiene:
isAuthenticated
: Si el usuario está autenticado.userData
: Los datos del usuario autenticado.token
: El JWT almacenado en localStorage
.Para simular una API, vamos a configurar Axios para hacer peticiones de autenticación.
javascript// api.js import axios from 'axios'; // Simulamos la URL de la API const apiUrl = 'https://api.example.com/login'; const loginApi = async (credentials) => { try { const response = await axios.post(apiUrl, credentials); return response.data; // Simulamos un JWT y datos de usuario } catch (error) { throw new Error('Error en el login'); } }; export { loginApi };
Vamos a crear una función para manejar el login y la interacción con el store de Zustand.
javascript// login.js import React, { useState } from 'react'; import useAuthStore from './authStore'; import { loginApi } from './api'; const Login = () => { const { login } = useAuthStore(); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const handleLogin = async (e) => { e.preventDefault(); try { const credentials = { username, password }; const { token, userData } = await loginApi(credentials); // Simulamos la respuesta de la API login(token, userData); // Almacenamos el token y los datos en el store setError(''); } catch (error) { setError('Credenciales incorrectas'); } }; return ( <div> <h2>Iniciar sesión</h2> <form onSubmit={handleLogin}> <div> <label>Usuario:</label> <input type="text" value={username} onChange={(e) => setUsername(e.target.value)} required /> </div> <div> <label>Contraseña:</label> <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} required /> </div> <button type="submit">Iniciar sesión</button> </form> {error && <p>{error}</p>} </div> ); }; export default Login;
Cada vez que la página se recarga, queremos asegurarnos de que el token persista y la sesión siga activa.
javascript// App.js import React, { useEffect } from 'react'; import useAuthStore from './authStore'; import Login from './Login'; const App = () => { const { isAuthenticated, token, userData, logout } = useAuthStore(); useEffect(() => { // Verificamos si el token existe en localStorage y lo usamos para actualizar el estado if (token) { // Aquí podemos simular la validación del token con la API // Si el token es válido, actualizamos el estado de la sesión. // Si no es válido, llamamos a logout() } }, [token]); return ( <div> {isAuthenticated ? ( <div> <h2>Bienvenido, {userData?.username}</h2> <button onClick={logout}>Cerrar sesión</button> </div> ) : ( <Login /> )} </div> ); }; export default App;
Para proteger rutas y mostrar contenido según el estado de autenticación, podemos hacer algo como esto:
javascript// ProtectedRoute.js import React from 'react'; import { Redirect } from 'react-router-dom'; import useAuthStore from './authStore'; const ProtectedRoute = ({ children }) => { const { isAuthenticated } = useAuthStore(); if (!isAuthenticated) { return <Redirect to="/login" />; } return children; }; export default ProtectedRoute;
Este componente puede envolver las rutas protegidas para que solo sean accesibles si el usuario está autenticado.
Con este sistema:
localStorage
, lo que permite persistir la sesión tras recargar la página.Este código es un punto de partida básico que puedes ampliar para manejar otros aspectos, como la validación del token con la API, manejo de errores más avanzado, o la creación de rutas protegidas.