¿Cómo evitar el acceso a las páginas de administración usando Node.js y React.js?

En muchos sitios web, el contenido disponible para el usuario final está limitado hasta que prueba su autenticidad iniciando sesión. Durante el desarrollo de aplicaciones MERN Stack, cuando el servidor está vinculado al cliente, es posible que deseemos limitar el páginas a las que accede el usuario a menos que haya iniciado sesión. En este artículo, echemos un vistazo a cómo el acceso a las páginas de administración está restringido usando React.js y Node.js.

Requisitos previos:

Módulos requeridos en el lado del cliente:

  • axios
  • reaccionar-enrutador-dom

Módulos requeridos en el lado del servidor:

  • Rápido
  • corazones

Configuración de cliente y servidor: 

Paso 1: Cree un repositorio npm usando el comando:

npm init --y

Paso 2: Cree un nuevo proyecto de cliente de reacción usando el comando:

npx create-react-app client

Paso 3: Cree un archivo de servidor en el directorio actual usando el comando:

touch server.js

Paso 4: cambie a la carpeta src en la carpeta del cliente y elimine todos los archivos con el siguiente comando:

cd client
cd src
rm *

Paso 5: crea una carpeta de páginas en la carpeta src

mkdir pages

Paso 6: en la carpeta src, cree los archivos App.js, index.js y PrivateRoute.js.

touch App.js index.js PrivateRoute.js

Paso 7: en la carpeta de páginas, cree archivos Home.js Admin.js.

cd pages
touch Home.js Admin.js

Paso 8: Instale Axios y react-router-dom en la carpeta del cliente

npm i axios react-router-dom

Paso 9: Instale express y cors en el lado del servidor

npm i express cors

Estructura del proyecto: La estructura de archivos en el proyecto se verá así.

Estructura del proyecto

Paso 10: Edición de index.js para vincular el archivo HTML y las bibliotecas de reacción.

Javascript

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
 
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

Paso 11: Edición de Home.js para ilustrar una página de inicio básica

Javascript

const Home = () => {
    return(
        <div className="home">
            <h1>This is the Home page</h1>
        </div>
    )
}
 
export default Home;

Paso 12: Edición de Admin.js para ilustrar una página de administración básica

Javascript

const Admin = () => {
    return(
        <div>
            <h1>Admin Page</h1>
        </div>
    )
}
 
export default Admin;

Paso 13: Creación de una ruta privada que impida el acceso a la página web a usuarios no autorizados . Esta ruta se puede utilizar para cualquier componente que necesite protección. La ruta privada esencialmente realiza una llamada API al servidor para verificar la autenticidad del usuario. Si se autentica con éxito, la ruta representa el supuesto componente; de ​​lo contrario, redirige a la página de inicio.

Javascript

// Importing the required libraries
import { Navigate } from "react-router-dom";
import { useEffect, useState } from "react";
const axios = require('axios');
 
 
// Private Route Component
// Params: login -> indicates the login state
//         children -> the child components of private route
const PrivateRoute = ({ login, children }) => {
 
  // Authentication Handler
  const authenticate = (login) => {
 
    setLoading(true);
 
    // HTTP Post Request
    axios({
      method: 'post',
      url: 'http://localhost:8000/admin',
      data: {
        logged: login,
      }
    }).then(({ data }) => {
      if(data.success){
        setAuth(true);
      }else{
        setAuth(false);
      }
      console.log(data.message);
      setLoading(false);
    }).catch((error) => {
      console.log(error);
      setLoading(false);
    })
  }
 
  // useState hook to inform the user about the loading state
  const [loading, setLoading] = useState(true);
 
  // useState hook to authorize the user
  const [auth, setAuth] = useState(false);
 
  // Authenticates the user whenever the
  // login state changes
  useEffect(() => {
    authenticate(login);
    return () => {
      setLoading(true);
    };
  }, [login])
 
  // If authenticated loads the required component
  // else redirects to the home page
  return loading ? (
    <h1>Loading...</h1>
  ) : auth ? children : (
    <Navigate to="/" />
  );
};
 
export default PrivateRoute;

Paso 14: Integrar todos los componentes en el archivo App.js. Los enrutadores se utilizan para navegar entre la página de inicio y la página de administración. Crearemos un componente de botón para iniciar sesión y cerrar sesión . Las etiquetas de enlace se crean con fines de navegación. El almacenamiento local se utiliza para mantener el estado de inicio de sesión entre renderizaciones posteriores.

Javascript

// Importing the required modules
import { BrowserRouter as Router, Routes,
    Route, Link } from "react-router-dom";
import Home from "./pages/Home";
import Admin from "./pages/Admin";
import PrivateRoute from "./PrivateRoute";
import { useEffect, useState } from "react";
 
const App = () => {
   
  // useState hook to keep track of the login state
  const [login, setLogin] = useState(() => {
 
    // Used local storage to sustain the login state
    if(!localStorage.getItem("login")){
      localStorage.setItem("login", "false");
      return false;
    }
    return JSON.parse(localStorage.getItem("login"));
  });
 
  // Updating the local storage whenever
  // the login state changes
  useEffect(() => {
    localStorage.setItem("login", JSON.stringify(login));
  }, [login]);
 
  // Click Handler updates the login state
  // when the button is clicked
  const click = () => {
    setLogin((prev) => {
      return !prev;
    });
  }
 
  return (
    <div className="App">
      <Router>
        <button onClick={() => click()}>
          {login? "Logout" : "Login"}
        </button>
        <Link to={"/admin"}>Admin</Link>
        <Link to={"/"}>Home</Link>
        <Routes>
          <Route path="/" element={<Home />} />
          {/* Protecting the Admin Page */}
          <Route
            path="/admin"
            element={
            <PrivateRoute login={login}>
              <Admin />
            </PrivateRoute>
            }
          />
        </Routes>
      </Router>
    </div>
  );
}
 
export default App;

Paso 15: Crear el servidor y escuchar las requests entrantes en el puerto 8000. Hemos creado una función de middleware para autenticar al usuario. Esta función de middleware se puede aplicar a cualquier ruta.

Javascript

// Importing the required modules
const express = require('express');
const cors = require('cors');
 
// Creating an express server
const app = express();
 
// Middleware to parse the data into JSON
app.use(express.json())
 
// Middleware to accept requests from localhost:3000
app.use(
    cors({
      origin: "http://localhost:3000",
      credentials: true,
    })
);
 
// Middleware Function to authenticate the user
const auth = (req, res, next) => {
    console.log(req.body);
    if(req.body.logged){
        next();
        return;
    }
    res.send({
        success: false,
        message: "Unauthorized Access"
    });
}
 
// Post request handler for the /admin route
app.post("/admin", auth, (req, res) => {
    res.send({
        success: true,
        message: "Successfully Authenticated"
    });
})
 
app.listen(8000, () => {
    console.log("Listening on port 8000")
})

Pasos para ejecutar la aplicación:

Ejecute el siguiente comando en la carpeta del cliente

npm start

Ejecute el siguiente comando en el directorio base

node server.js

Producción:

Aplicación web básica

Si todo funciona según lo previsto, deberíamos estar viendo:

  • El siguiente resultado en el lado del servidor cuando cerramos sesión e iniciamos sesión

Salida del lado del servidor

  • El siguiente resultado en el lado del cliente cuando cerramos sesión e iniciamos sesión

Salida del lado del cliente

Salida final:

Salida final

Publicación traducida automáticamente

Artículo escrito por tejsidda34 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

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