javascript - 如何动态使用react路由

标签 javascript reactjs react-router react-hooks react-router-dom

我有一个应用程序,其中我有两个登录名,一个用于 superAdmin和其他“管理员”。

  • 我有几个页面一个是常见的(主页),两个用户都有多余的。
  • 然后我还有其他几页是 admin和其他人为superAdmin .
  • 现在,当我打开我的页面时,我正试图走“/”这条路线(我的家路线)。
    我想做的
  • 现在,如果我以管理员身份登录并且管理员用户正在输入一些 superAdmin地址栏中的 url 我希望将其重定向到当前的管理路由
  • superAdmin 也是如此以及
  • 两个用户我都想限制多余的彼此路线
  • 如果我是管理员用户或 super 管理员用户并尝试登录并尝试过多的经过身份验证的路由,我应该重定向到主页

  • 我做了什么
    我在这里创建了一个组件(动态路由),我正在检查用户正在尝试做什么。
    在我的路由文件中的 route.js 中,我将 Prop 传递为 guest , superAdminadmin 动态路由.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} />;
        }
    }
    
    我的 route.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/>
    
    我面临的问题
    我不知道我面临的问题是在登录时将我重定向到该路线,但内容未加载
    如果我在该页面上控制台某些内容,我无法获得该内容,则该页面将变为空白。
    I am following this lecture from 25:00 timing
    I am getting this blank page
    已编辑
    Here is my code sand box
    请检查这个
    编辑
    admin 和 super admin 将在不同的浏览器中登录,所以只是不希望 admin 访问 super admin,反之亦然,如果他们输入 url

    最佳答案

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

    Demo on 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;
    
    二:您需要授权组件来处理如下路由:
    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);
    
    第三:您需要 authRoles 文件或远程来管理客户端上的 Angular 色,如下所示:
    /**
     * Authorization Roles
     */
    const authRoles = {
      admin: ["admin"],
      superAdmin: ["superAdmin"],
      user: ["user"],
      onlyGuest: []
    };
    
    export default authRoles;
    
    第四:如果你想继续这个逻辑,你必须实现你的页面结构,如下所示:
    src
     |---pages
          |---home
               |---HomePage.jsx
               |---HomePageConfig.jsx
          |
          |- The rest of the pages should be implemented in the same way
    
    例如:当你想实现一个只有管理员才能看到的页面时(管理员主页配置):
    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"))
        }
      ]
    };
    
    或者大家都能看到的首页:
    import React from "react";
    
    export const HomePageConfig = {
      routes: [
        {
          path: "/",
          exact: true,
          component: React.lazy(() => import("./HomePage"))
        }
      ]
    };
    
    根据上面的例子,你可以输入auth proprole在这里,限制对页面的访问。
    为了更深入地了解这个逻辑,我在 Codesandbox 中实现了它,您可以通过以下链接查看:
    Demo on Codesandbox

    Notice: The above demo needs to be more complete, and instead of storing user roles in the state, it is better to use state management packages (redux, ...) and also perform login operations through cookies.

    关于javascript - 如何动态使用react路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66049458/

    相关文章:

    javascript - 如何使用 angularjs webapp 渲染登陆页面?

    javascript - 如何过滤数字数组并采取一定的间隔?

    jquery - 如何修复此错误: "Module not found :can' t resolve popper. js”

    javascript - React - 在 componentWillReceiveProps 中设置超时

    javascript - 如何在同一页面的多个位置使用同一个 React 应用程序?

    reactjs - 我可以为两条路线使用相同的路线处理程序吗

    javascript - React Router 的 HashRouter 重定向到 <base> 标签 url

    reactjs - 在哪里使用 URL 参数中的值设置 React 组件的状态

    javascript - JSON 删除也会删除源变量中的属性

    javascript - jquery 列表项类切换