【问题标题】:React.js Simple Role Based RoutesReact.js 简单的基于角色的路由
【发布时间】:2022-01-14 01:33:03
【问题描述】:

这是我第一次使用基于角色的路由。我们为玩家提供了一个功能齐全的应用程序。现在,我们需要为该应用添加 Trainer 页面。我们将用户存储在 Firebase 中,我们需要手动为用户添加新密钥,例如 trainer: true|false。在 React Application 中,我们将重定向用户。 例如:

    if (user.trainer) {
      <Redirect to={"/trainer"}
    } else {
      <Redirect to={"/"}
    }

我们需要管理其他页面。例如:当教练想要导航到另一个不允许的页面时,我们需要将他们重定向回"/trainer",否则对面的普通玩家无法导航到"/trainer"页面。有人可以帮我吗?

我有这样的集中路线;

import SignInSignUp from "./pages/SignInSignUp/SignInSignUp";
import Home from "./pages/Home/Home";
import Help from "./pages/Help/Help";
import Profile from "./pages/Profile/Profile";
import Exercises from "./pages/Exercises/Exercises";
import Trainer from "./pages/Trainer/Trainer";


export const routes = [
  { isProtected: false, path: "/auth", component: SignInSignUp },
  { isProtected: true, path: "/", component: Home },
  { isProtected: true, path: "/help", component: Help },
  { isProtected: true, path: "/profile", component: Profile },
  { isProtected: true, path: "/exercises", component: Exercises },
  { isProtected: true, path: "/trainer", component: Trainer },
];

然后我像这样循环路线;

import "./App.scss";
import { Switch, Route, Redirect } from "react-router-dom";
import Navbar from "./components/Navbar/Navbar";
import ProtectedRouter from "./utils/ProtectedRouter";

import { routes, navbarPaths } from "./routes";

function App() {


  return (
    <div className="App">

      <Switch>
        {routes.map(
          ({
            isProtected,
            component,
            path,
          }: {
            isProtected: boolean;
            component: any;
            path: string;
          }) => {
            const RouteWrapper = isProtected ? ProtectedRouter : Route;
            return (
              <RouteWrapper
                exact
                key={path}
                path={path}
                component={component}
              />
            );
          }
        )}
        <Route exact path="/player*" render={() => (<Redirect to={"/"} />)} />          
      </Switch>

      <Route path={navbarPaths} exact component={Navbar} />
    </div>
  );
}

export default App;

这是我的受保护路由组件

import { Route, Redirect } from "react-router-dom";
import { useAuthStatus } from "../firebase/useAuthStatus.hook";

const ProtectedRouter = ({ component: Component, ...rest }: any) => {
  const { loggedIn, checkingStatus } = useAuthStatus();
  return (
    <Route
      {...rest}
      render={(props) => {
        if (!checkingStatus) {
          if (loggedIn) {
            return <Component />;
          } else {
            return (
              <Redirect
                to={{
                  pathname: "/auth",
                  state: {
                    from: props.location,
                  },
                }}
              />
            );
          }
        }
      }}
    />
  );
};

export default ProtectedRouter;

【问题讨论】:

  • 您只是在问如何在您的ProtectedRouter 组件中进行有条件的重定向吗?您在哪里访问 user 对象以检查角色?

标签: reactjs react-router-dom role-based-access-control


【解决方案1】:

如果我正确理解您的问题,您希望根据用户的角色有条件地更改 ProtectedRouter 组件中的重定向目标。

根本没有经过测试,但我相信以下内容将解决您的问题。

重构您的ProtectedRoute 以获取isProtectedtrainer 和传递的路由道具。如果路由不受保护,请检查用户的trainer 角色是否匹配,并有条件地呈现路由或重定向到"/trainer""/"。如果路由受到保护并且用户已通过身份验证,请再次检查用户的 trainer 角色是否匹配并有条件地呈现路由或重定向到 "/trainer" 或 @987654330 @。

const ProtectedRouter = ({ isProtected, trainer, ...props }: any) => {
  const location = useLocation();
  const { loggedIn, checkingStatus } = useAuthStatus();
  const user = /* business logic to get user object */

  if (checkingStatus) return null;

  if (!isProtected || loggedIn) {
    return user.trainer === trainer
      ? <Route {...props} />
      : <Redirect to={user.trainer ? "/trainer" : "/"} />;
  }

  return (
    <Redirect
      to={{
        pathname: "/auth",
        state: { from: location },
      }}
    />
  );
};

更新routes 以添加trainer 属性。

export const routes = [
  { isProtected: false, path: "/auth", component: SignInSignUp },
  { isProtected: true, path: "/", component: Home },
  { isProtected: true, path: "/help", component: Help },
  { isProtected: true, path: "/profile", component: Profile },
  { isProtected: true, path: "/exercises", component: Exercises },
  { isProtected: true, path: "/trainer", component: Trainer, trainer: true },
];

更新App,将所有路由映射到自定义路由组件。

function App() {
  ...

  return (
    <div className="App">
      <Switch>
        {routes.map(props => <ProtectedRouter key={props.path} exact {...props} />)}
        <Route exact path="/player*" render={() => (<Redirect to={"/"} />)} />          
      </Switch>

      <Route path={navbarPaths} exact component={Navbar} />
    </div>
  );
}

【讨论】:

    猜你喜欢
    • 2017-05-10
    • 1970-01-01
    • 2016-06-12
    • 2012-01-01
    • 1970-01-01
    • 2023-03-30
    • 2015-07-17
    • 1970-01-01
    • 2021-08-26
    相关资源
    最近更新 更多