Reactjs 如何控制前端React JS-MERN应用程序上的用户角色

Reactjs 如何控制前端React JS-MERN应用程序上的用户角色,reactjs,Reactjs,MERN应用程序(MongoDB、Express、ReactJS、NodeJS)-在后端,我使用令牌控制登录用户,并根据角色授予用户访问权限 问题是:如果用户是管理员或客户端,如何控制前端(ReactJS)用户的角色 例: 如果用户已登录,我会将令牌从后端发送到前端,如果用户已登录,我可以控制如下路由: if(token){ //if user is logged <Route path="/dashboard" exact

MERN应用程序(MongoDB、Express、ReactJS、NodeJS)-在后端,我使用令牌控制登录用户,并根据角色授予用户访问权限

问题是:如果用户是管理员或客户端,如何控制前端(ReactJS)用户的角色

例: 如果用户已登录,我会将令牌从后端发送到前端,如果用户已登录,我可以控制如下路由:

if(token){                                //if user is logged
  <Route path="/dashboard" exact>
     <Products/>                          //Products Page
  </Route>
}else{
  <Route path="/dashboard" exact>
     <Page1 />                          //AnyPage
  </Route>
}
if(token){//if用户已登录
//产品页
}否则{
//任意页
}
我只想让管理员用户访问用户页面:

if(token && role === 'admin'){                                //if user is logged and role is admin
  <Route path="/dashboard" exact>
     <Users />                          //Users Page
  </Route>
}...
if(令牌和角色==='admin'){//如果用户已登录且角色为admin
//用户页面
}...
我可以在后端控制这件事,我只想在前端了解关于这个问题的任何其他想法。
谢谢:)

你的思路大体正确。这种模式(检测登录和/或角色状态以及有条件地呈现组件)通常称为“受保护路由”

你可以这样做:

const ProtectedRoute = ({showRoute, ...props}) => {
  if (showRoute) {
    return <Route {...props} />
  } else {
    // return null to simply not render the route if not logged in
    return null;
    // or you could return <Redirect to='/foo' /> to send them elsewhere
  }
}

const App = () => {
  const isLoggedIn = true;

  return (
    <Router>
      <ProtectedRoute showRoute={isLoggedIn} path="/dashboard" component={Users} />
    </Router>
  );
}

在这种情况下我会做什么:

  • 当用户登录时,API应该返回他们的信息,包括权限。将该信息存储在状态中

  • 创建一个函数,
    checkUserPermission(user={roles:[]},permission)
    。此函数接受
    用户
    对象、
    权限
    字符串(即
    “route.admin”
    “component.Authenticate”
    )并根据用户的访问级别返回true或false。这将是一个决定是否允许当前用户这样做或那样做的地方。它可以由简单的属性检查(
    if(user.role==='admin')
    )或更复杂的内容组成(参见示例)

  • 创建
    securedulote
    组件,该组件是
    Route
    的包装器,但会获取
    user
    permission
    参数,并在用户看不到此路由时重定向

  • 使用
    checkUserPermission
    函数有条件地呈现链接或组件

  • 正如在其他答案中已经提到的,API必须对每个请求进行自己的权限检查,因为在UI端隐藏东西并不能阻止恶意和有知识的用户


  • //src/utils/checkUserPermission.js
    导出默认函数checkUserPermission(用户={roles:[]},权限){
    const AllowAccess for角色={
    “route.admin”:[“admin”],
    “路由.已验证”:[“用户”,“管理员”],
    “route.home”:[“*”],//表示“任何角色”
    “component.Authenticate”:[“*”、“!user”、“!admin”]、//除user和admin之外的任何角色
    “component.BecomeAdmin”:[“用户”],
    “组件.注销”:[“用户”,“管理员”]
    };
    //若我们在列表中并没有这样的权限,每个人都会被拒绝访问
    if(!Array.isArray(allowAccessForRoles[permission])){
    返回false;
    }
    //检查是否有任何用户角色明确拒绝访问
    for(user.roles的常量角色){
    if(AllowAccess角色[权限]。包括(“!”+角色)){
    返回false;
    }
    }
    //如果允许的角色列表包含“*”,则允许每个人访问
    if(AllowAccess角色[权限]。包括(“*”){
    返回true;
    }
    //检查是否有任何用户角色允许访问
    for(user.roles的常量角色){
    if(AllowAccess角色[权限]。包括(角色)){
    返回true;
    }
    }
    返回false;
    }
    //src/securedroote
    从“React”导入React;
    从“react router dom”导入{Route,Redirect};
    从“/utils/checkUserPermission”导入checkUserPermission;
    常数securedroote=({
    用户,
    许可,
    重定向至=“/”,
    儿童
    休息
    }) => {
    const allowed=checkUserPermission(用户,权限);
    如果(允许){
    返回子项}/>;
    }
    返回(
    (
    )}
    />
    );
    };
    导出默认值;
    //src/App.js
    从“React”导入React,{useState};
    导入“/styles.css”;
    从“react Router dom”导入{BrowserRouter as Router,Switch,Link};
    从“/securedroote”导入securedroote;
    从“/utils/checkUserPermission”导入checkUserPermission;
    const AdminPage=()=>管理员页面为管理员打开;
    const AuthenticatedPage=()=>(
    已为用户和管理员打开验证页面
    );
    const HomePage=()=>主页对所有人开放;
    导出默认函数App(){
    const[user,setUser]=useState();
    返回(
    转到主页
    {checkUserPermission(用户,“route.authenticated”)(
    转到已验证页面
    ):null}
    {checkUserPermission(用户,“route.admin”)(
    转到管理页面
    ):null}
    {checkUserPermission(用户,“component.Authenticate”)(
    setUser({角色:[“用户”]})}>
    认证
    ):null}
    {checkUserPermission(用户,“component.BecomeAdmin”)(
    setUser({roles:[“admin”]})}>
    成为管理员
    ):null}
    {checkUserPermission(用户,“component.LogOut”)(
    setUser()}>
    注销
    ):null}
    );
    }
    
    我可以使用令牌控制用户是否登录,如果用户登录则渲染组件,问题是如何控制reactjs上的用户是否登录以及该用户具有哪个角色(“管理员”或“简单用户”)。如果要了解用户具有什么角色,只需让后端将该数据与token@besartm可以那么,当恶意用户手动将其角色设置为“a”时会发生什么情况
    const App = () => {
      const isLoggedIn = true;
    
      return (
        <Router>
          <Switch>
            <ProtectedRoute showRoute={isLoggedIn} path="/dashboard" component={LoggedInDashboard} />
            <Route path="/dashboard" component={LoggedOutDashboard} />
          </Switch>
        </Router>
      );
    }
    
    const userLogin = React.createContext(false);
    
    const LoggedInRoute = (props) => {
      const showRoute = useContext(userLogin);
    
      if (showRoute) {
        return <Route {...props} />
      } else {
        return null;
      }
    }
    
    const App = () => {
      const [userLoggedIn, setUserLoggedIn] = React.useState(false);
    
      return (
        <userLogin.Provider value={userLoggedIn}>
          <Router>
            <LoggedInRoute path="/dashboard" component={Users} />
          </Router>
        </userLogin.Provider>
      );
    }
    
    //src/utils/checkUserPermission.js
    export default function checkUserPermission(user = { roles: [] }, permission) {
      const allowAccessForRoles = {
        "route.admin": ["admin"],
        "route.authenticated": ["user", "admin"],
        "route.home": ["*"], //means "Any role"
        "component.Authenticate": ["*", "!user", "!admin"], //Any role except user and admin
        "component.BecomeAdmin": ["user"],
        "component.LogOut": ["user", "admin"]
      };
    
      //If we don't have such permission in list, access denied for everyone
      if (!Array.isArray(allowAccessForRoles[permission])) {
        return false;
      }
    
      //Check if any of user's roles explicitly denies access
      for (const role of user.roles) {
        if (allowAccessForRoles[permission].includes("!" + role)) {
          return false;
        }
      }
    
      //If list of allowed roles contains '*', access allowed for everyone
      if (allowAccessForRoles[permission].includes("*")) {
        return true;
      }
    
      //Check if any of user's roles allowes access
      for (const role of user.roles) {
        if (allowAccessForRoles[permission].includes(role)) {
          return true;
        }
      }
    
      return false;
    }
    
    //src/SecuredRoute
    import React from "react";
    import { Route, Redirect } from "react-router-dom";
    import checkUserPermission from "./utils/checkUserPermission";
    
    const SecuredRoute = ({
      user,
      permission,
      redirectTo = "/",
      children,
      ...rest
    }) => {
      const allowed = checkUserPermission(user, permission);
    
      if (allowed) {
        return <Route {...rest} render={() => children} />;
      }
    
      return (
        <Route
          {...rest}
          render={({ location }) => (
            <Redirect
              to={{
                pathname: redirectTo,
                state: { from: location }
              }}
            />
          )}
        />
      );
    };
    
    export default SecuredRoute;
    
    //src/App.js
    import React, { useState } from "react";
    import "./styles.css";
    import { BrowserRouter as Router, Switch, Link } from "react-router-dom";
    import SecuredRoute from "./SecuredRoute";
    import checkUserPermission from "./utils/checkUserPermission";
    
    const AdminPage = () => <div>Admin page is open for admins</div>;
    
    const AuthenticatedPage = () => (
      <div>Authenticated page is open for users and admins</div>
    );
    
    const HomePage = () => <div>Home page is open for everyone</div>;
    
    export default function App() {
      const [user, setUser] = useState();
    
      return (
        <Router>
          <div className="App">    
            <div className="Nav">
              <div>
                <Link to="/">Go to Home Page</Link>
              </div>
              {checkUserPermission(user, "route.authenticated") ? (
                <div>
                  <Link to="/authenticated">Go to Authenticated Page</Link>
                </div>
              ) : null}
              {checkUserPermission(user, "route.admin") ? (
                <div>
                  <Link to="/admin">Go to Admin Page</Link>
                </div>
              ) : null}
            </div>
    
            <div className="Controls">
              {checkUserPermission(user, "component.Authenticate") ? (
                <button type="button" onClick={() => setUser({ roles: ["user"] })}>
                  Become authenticated
                </button>
              ) : null}
    
              {checkUserPermission(user, "component.BecomeAdmin") ? (
                <button type="button" onClick={() => setUser({ roles: ["admin"] })}>
                  Become admin
                </button>
              ) : null}
    
              {checkUserPermission(user, "component.LogOut") ? (
                <button type="button" onClick={() => setUser()}>
                  Log out
                </button>
              ) : null}
            </div>
    
            <div className="Main">
              <Switch>
                <SecuredRoute user={user} permission="route.home" exact path="/">
                  <HomePage />
                </SecuredRoute>
                <SecuredRoute
                  user={user}
                  permission="route.authenticated"
                  path="/authenticated"
                >
                  <AuthenticatedPage />
                </SecuredRoute>
                <SecuredRoute user={user} permission="route.admin" path="/admin">
                  <AdminPage />
                </SecuredRoute>
              </Switch>
            </div>
          </div>
        </Router>
      );
    }