Open In App

How to prevent access to admin pages using Node.js and React.js ?

Last Updated : 17 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

To prevent access to admin pages using Node.js and React.js is a common task to avoid unauthorized access. In many websites, the content available to the end-user is limited until he/she proves his/her authenticity by logging in. During the development of MERN Stack Applications, when the server is linked to the client, we may want to limit the pages accessed by the user unless he is logged in.

Pre-requisites:

Approach:

To prevent access to admin pages using Node.js and React.js we will set the user-logged data in the localStorage. When the user log is true the server check and authorize the user to access the admin page with a success alert.

Steps to Create React Application and Server Setup: 

Step 1: Create an npm repository using the command:

npm init --y

Step 2: Create a new react client project by using the command:

npx create-react-app client

Step 3: Create a server file in the current directory using the command:

touch server.js

Step 4: Switch to the src folder in the client folder and remove all the files using the following command:

cd client
cd src
rm *

Step 5: Create a pages folder in the src folder

mkdir pages

Step 6: In the src folder create App.js, index.js, and PrivateRoute.js files.

touch App.js index.js PrivateRoute.js

Step 7: In the pages folder create Home.js Admin.js files.

cd pages
touch Home.js Admin.js

Step 8: Install Axios and react-router-dom in the client folder

npm i axios react-router-dom

The dependencies in package.json file in client directory

"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.6.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.18.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},

Step 9: Install express and cors in the server-side

npm i express cors

The dependencies in package.json file in server

"dependencies": {
"cors": "^2.8.5",
"express": "^4.18.2"
}

Project Structure:

Project Structure

Example: This example implements the Client Side application creating Home, Admin pages and PrivateRoute component.

Javascript




// Filename - client/src/App.js
 
// 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;


Javascript




// Filename - client/src/pages/Home.js
 
const Home = () => {
    return (
        <div className="home">
            <h1>This is the Home page</h1>
        </div>
    );
};
 
export default Home;


Javascript




// Filename - client/src/pages/Admin.js
 
const Admin = () => {
    return (
        <div>
            <h1>Admin Page</h1>
        </div>
    );
};
 
export default Admin;


Javascript




// Filename - client/src/PrivateRoute.js
 
// 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;


Example : This example implements server with middleware using express and cors packages Creating the server and listening to incoming requests on port 8000. We have created a middleware function to authenticate the user. This middleware function can be applied to any route.

Javascript




// Filename - server.js
 
// 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");
});


Steps to run the application: Run the following command in the client folder

npm start

Run the following command in the base directory

node server.js

Output: This output will be visible on the http://localhost:3000/ on the browser window.

Final Output



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads