如何动态使用反应路由

man*_*kur 7 javascript reactjs react-router react-router-dom react-hooks

我有一个应用程序,我有两个登录名,一个superAdmin是“管理员”,另一个是“管理员”。

  1. 我有几个页面,其中一个是常见的(主页),两个用户都超过了这个页面。

  2. 然后我还有其他几个页面,其中一些用于admin,另一些用于superAdmin.

  3. 现在,当我打开我的页面时,我正试图走“/”这条路线(我的家乡路线)。 我想做什么

  4. 现在,如果我以管理员身份登录并且管理员用户superAdmin在地址栏中键入一些url,我希望将其重定向到当前的管理员路由

  5. 同去的superAdmin还有

  6. 我想限制用户使用过多的彼此路线

  7. 如果我是 admin 用户或 superAdmin 用户并尝试登录并尝试过多的经过身份验证的路由,我应该重定向到主页

我做了什么

我在这里创建了一个组件(动态路由),我正在检查用户正在尝试做什么。在路由文件中的 route.js 中,我将 props 传递为guestsuperAdmin并且admin

Dynamicroute.js 代码

我已经创建了我的上下文来存储用户登录后

    export default function Dynamicroute(props) {
    const { user } = useAuthState();  // this I am getting from my context
    console.log(user);

    if (props.partner && !user) {
        console.log('admin not logedin');
        return <Redirect to="/admin" />;
    } else if (props.admin && !user) {
        console.log('superAdmin not loged in');
        return <Redirect to="/superAdmin" />;
    } else if (props.admin && user.role === 'admin') {
        console.log('admin logedin');
        return <Redirect to="/admin_home" />;
    } else if (props.admin && user.role === 'superAdmin') {
        console.log('super admin loged in');
        return <Redirect to="/superadmin_home" />;
    } else if (props.guest && user) {
        console.log('guest');
        return <Redirect to="/" />;
    } else {
        return <Route component={props.component} {...props} />;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的路线.js

<DuynamicRoute exact path="/" component={Home} guest />
<DuynamicRoute path="/admin" component={loginAdmin} guest />
<DuynamicRoute path="/superAdmin" component={loginSuperAdmin} guest />
<DuynamicRoute path="/admin_home" component={admin_home} admin/>
<DuynamicRoute path="/superAdmin_home" component={superAdmin_home} superAdmin/>
Run Code Online (Sandbox Code Playgroud)

我面临的问题

我不知道我面临的问题是在登录时将我重定向到该路由,但内容未加载

我从 25:00 开始关注这个讲座

我得到这个空白页

已编辑

这是我的代码沙箱

请检查这个

编辑

admin 和 super admin 将在不同的浏览器中登录,所以如果他们输入彼此的路由,则不希望 admin 访问超级管理员,反之亦然

Moh*_*deh 6

为了更好地管理和开发程序以及最佳实践,在 React.js 中进行授权如下:

Codesandbox 上的演示

第一:您需要一个class进行检查permissionsroutes/pages configs如下所示:

class AppUtils {
  static setRoutes(config) {
    let routes = [...config.routes];

    if (config.auth) {
      routes = routes.map((route) => {
        let auth = config.auth ? [...config.auth] : null;
        auth = route.auth ? [...auth, ...route.auth] : auth;
        return {
          ...route,
          auth
        };
      });
    }

    return [...routes];
  }

  static generateRoutesFromConfigs(configs) {
    let allRoutes = [];
    configs.forEach((config) => {
      allRoutes = [...allRoutes, ...this.setRoutes(config)];
    });
    return allRoutes;
  }

  static hasPermission(authArr, userRole) {
    /**
     * If auth array is not defined
     * Pass and allow
     */
    if (authArr === null || authArr === undefined) {
      // console.info("auth is null || undefined:", authArr);
      return true;
    } else if (authArr.length === 0) {
      /**
       * if auth array is empty means,
       * allow only user role is guest (null or empty[])
       */
      // console.info("auth is empty[]:", authArr);
      return !userRole || userRole.length === 0;
    } else {
      /**
       * Check if user has grants
       */
      // console.info("auth arr:", authArr);
      /*
            Check if user role is array,
            */
      if (userRole && Array.isArray(userRole)) {
        return authArr.some((r) => userRole.indexOf(r) >= 0);
      }

      /*
            Check if user role is string,
            */
      return authArr.includes(userRole);
    }
  }
}

export default AppUtils;
Run Code Online (Sandbox Code Playgroud)

第二:您需要授权组件来处理如下路由:

import React, { Component } from "react";
import AppUtils from "utils/AppUtils";
import { matchRoutes } from "react-router-config";
import { withRouter } from "react-router-dom";
import AppContext from "context/AppContext";

class AppAuthorization extends Component {
  constructor(props, context) {
    super(props);
    const { routes } = context;
    this.state = {
      accessGranted: true,
      routes
    };
  }

  componentDidMount() {
    if (!this.state.accessGranted) {
      this.redirectRoute();
    }
  }

  componentDidUpdate() {
    if (!this.state.accessGranted) {
      this.redirectRoute();
    }
  }

  static getDerivedStateFromProps(props, state) {
    const { location, userRole } = props;
    const { pathname } = location;

    const matched = matchRoutes(state.routes, pathname)[0];

    return {
      accessGranted: matched
        ? AppUtils.hasPermission(matched.route.auth, userRole)
        : true
    };
  }

  shouldComponentUpdate(nextProps, nextState) {
    return nextState.accessGranted !== this.state.accessGranted;
  }

  redirectRoute() {
    const { location, userRole, history } = this.props;
    const { pathname, state } = location;
    const redirectUrl = state && state.redirectUrl ? state.redirectUrl : "/";

    /*
        User is guest
        Redirect to Login Page
        */
    if (!userRole || userRole.length === 0) {
      history.push({
        pathname: "/login",
        state: { redirectUrl: pathname }
      });
    } else {
      /*
        User is member
        User must be on unAuthorized page or just logged in
        Redirect to dashboard or redirectUrl
        */
      history.push({
        pathname: redirectUrl
      });
    }
  }

  render() {
    // console.info('App Authorization rendered', accessGranted);
    return this.state.accessGranted ? (
      <React.Fragment>{this.props.children}</React.Fragment>
    ) : null;
  }
}

// AppAuthorization.defaultProps = {
//   userRole: [] // You can manage roles by redux or any state managements
// };

AppAuthorization.contextType = AppContext;

export default withRouter(AppAuthorization);
Run Code Online (Sandbox Code Playgroud)

第三:您需要 authRoles 文件或远程来管理客户端上的角色,如下所示:

/**
 * Authorization Roles
 */
const authRoles = {
  admin: ["admin"],
  superAdmin: ["superAdmin"],
  user: ["user"],
  onlyGuest: []
};

export default authRoles;
Run Code Online (Sandbox Code Playgroud)

第四:如果你想继续这个逻辑,你必须实现你的页面结构如下:

src
 |---pages
      |---home
           |---HomePage.jsx
           |---HomePageConfig.jsx
      |
      |- The rest of the pages should be implemented in the same way
Run Code Online (Sandbox Code Playgroud)

例如:当你想实现一个只有管理员才能看到的页面时(管理员主页配置):

import React from "react";
import authRoles from "auth/authRoles";

export const AdminHomePageConfig = {
  auth: authRoles.admin,
  routes: [
    {
      path: "/admin",
      exact: true,
      component: React.lazy(() => import("./HomePage"))
    }
  ]
};
Run Code Online (Sandbox Code Playgroud)

或者大家都能看到的首页:

import React from "react";

export const HomePageConfig = {
  routes: [
    {
      path: "/",
      exact: true,
      component: React.lazy(() => import("./HomePage"))
    }
  ]
};
Run Code Online (Sandbox Code Playgroud)

根据上面的示例,您可以auth proprole此处输入和,以限制对页面的访问。

为了更仔细地了解这个逻辑,我在 Codesandbox 中实现了它,您可以通过下面的链接看到它:

Codesandbox 上的演示

注意:上面的demo需要比较完整,最好不要把用户角色存储在状态中,最好使用状态管理包(redux,...),也可以通过cookies进行登录操作。