如何使用Node.js和React.js防止访问管理员页面

如何使用Node.js和React.js防止访问管理员页面

在许多网站上,直到终端用户通过登录证明自己的真实性之前,可供其访问的内容是有限的。在开发MERN堆栈应用程序时,当服务器连接到客户端时,我们可能希望限制用户访问的页面,除非他已登录。在本文中,让我们来看看如何使用React.js和Node.js限制访问管理页面。

先决条件:

  • 函数组件
  • React Hooks
  • React Router V6
  • 基本CRUD操作

客户端所需模块:

  • axios
  • react-router-dom

服务器端所需模块:

  • express
  • cors

客户端和服务器设置:

步骤1: 使用以下命令创建npm仓库:

npm init --y

步骤2: 使用以下命令创建一个新的React客户端项目:

npx create-react-app client

步骤3: 使用以下命令在当前目录下创建一个服务器文件:

touch server.js

步骤4: 切换到client文件夹中的src文件夹,并使用以下命令删除所有文件:

cd client
cd src
rm *

步骤5: 在src文件夹中创建一个pages文件夹

mkdir pages

步骤6: 在src文件夹中创建App.js、index.js和PrivateRoute.js文件。

touch App.js index.js PrivateRoute.js

步骤7: 在pages文件夹中创建Home.js和Admin.js文件。

cd pages
touch Home.js Admin.js

步骤8: 在客户端文件夹中安装 Axios 和 react-router-dom

npm i axios react-router-dom

步骤9: 在服务器端安装express和cors

npm i express cors

项目结构:

项目中的文件结构如下所示。

如何使用Node.js和React.js防止访问管理员页面

步骤10: 编辑index.js文件以链接HTML文件和React库。

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

步骤11: 编辑Home.js,展示一个基本的主页

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

步骤12: 编辑 Admin.js文件以展示一个基本的管理页面

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

步骤13: 创建一个 私有路由 ,阻止未经授权的用户访问网页。任何需要受保护的组件都可以使用该路由。私有路由本质上通过向服务器发起 API 调用来检查用户的真实性。如果验证成功,路由将呈现相应的组件,否则将重定向到主页。

// 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;

步骤14: 整合 所有组件到 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;

步骤15: 创建 服务器 并监听8000端口上的传入请求。我们创建了一个中间件功能来验证用户。这个中间件功能可以应用到任何路由。

// 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")
})

运行应用程序的步骤:

在客户端文件夹中运行以下命令

npm start

在基础目录下运行以下命令

node server.js

输出结果:

如何使用Node.js和React.js防止访问管理员页面

如果一切正常,我们应该能够看到:

  • 当我们登出和登录时,在服务器端会出现以下输出

如何使用Node.js和React.js防止访问管理员页面

  • 当我们注销并登录时,客户端会输出以下内容

如何使用Node.js和React.js防止访问管理员页面

最终输出:

如何使用Node.js和React.js防止访问管理员页面

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程