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

📅  最后修改于: 2022-05-13 01:55:52.667000             🧑  作者: Mango

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

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

先决条件:

  • 功能组件
  • 反应钩子
  • 反应路由器 V6
  • 基本 CRUD 操作

客户端所需的模块:

  • axios
  • 反应路由器dom

服务器端所需的模块:

  • 表示
  • 科尔斯

客户端和服务器设置:

第 1 步:使用以下命令创建一个 npm 存储库:

npm init --y

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

npx create-react-app client

第三步:在当前目录下创建一个服务器文件,使用命令:

touch server.js

第四步:切换到客户端文件夹中的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

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

项目结构

第 10 步:编辑 index.js 以链接 HTML 文件和反应库。

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


Javascript
const Home = () => {
    return(
        
            

This is the Home page

        
    ) }   export default Home;


Javascript
const Admin = () => {
    return(
        
            

Admin Page

        
    ) }   export default Admin;


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 ? (
    

Loading...

  ) : auth ? children : (        ); };   export default PrivateRoute;


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 (
    
                        Admin         Home                    } />           {/* Protecting the Admin Page */}                                                    }           />                     
  ); }   export default App;


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


第 11 步:编辑 Home.js 以说明基本主页

Javascript

const Home = () => {
    return(
        
            

This is the Home page

        
    ) }   export default Home;

第 12 步:编辑 Admin.js 以说明基本的管理页面

Javascript

const Admin = () => {
    return(
        
            

Admin Page

        
    ) }   export default Admin;

第 13 步:创建私有路由,防止未经授权的用户访问网页。该路由可用于任何需要保护的组件。私有路由本质上是对服务器进行 API 调用以检查用户的真实性。如果成功通过身份验证,则该路由将呈现假定的组件,否则它将重定向到主页。

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 ? (
    

Loading...

  ) : auth ? children : (        ); };   export default PrivateRoute;

第 14 步:集成App.js文件中的所有组件。路由器用于在主页和管理页面之间导航。我们将创建一个按钮组件登录注销链接标签是为导航目的而创建的。本地存储用于维持后续重新渲染之间的登录状态。

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 (
    
                        Admin         Home                    } />           {/* Protecting the Admin Page */}                                                    }           />                     
  ); }   export default App;

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

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

运行应用程序的步骤:

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

npm start

在基本目录中运行以下命令

node server.js

输出:

基本网络应用

如果一切都按预期工作,我们应该看到:

  • 当我们注销和登录时,服务器端的以下输出

服务器端输出

  • 当我们注销和登录时,客户端的以下输出

客户端输出

最终输出:

最终输出