繁体   English   中英

使用私有路由构建路由数组

[英]Build route array with Private Route

我有 3 条路线 /x /y 和 /z 只有我的管理员可以输入,我的员工可以输入的 2 条路线 /a 和 /b 以及每个人都可以输入的 4 条路线,包括我的客户。 把这个逻辑放在哪里最好? 私有路由组件? 我正在尝试构建它,但到目前为止失败了。 这就是我所拥有的:

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import jwt_decode from 'jwt-decode';
import setAuthToken from '../utils/setAuthToken';
import { setCurrentUser, logoutUser } from '../actions/authActions';
import { Provider } from 'react-redux';
import store from '../store';
import Navbar from '../components/Navbar/Navbar';
import Register from '../components/Auth/Register';
import Login from '../components/Auth/Login';
import PrivateRoute from '../components/PrivateRoute/PrivateRoute';
import Charts from '../components/Dashboard/Charts';
import Places from '../components/Places/Places';
import Clients from '../components/Clients/Clients';
import SearchVehicles from '../components/Clients/SearchVehicles';
import Profile from '../components/Clients/Profile';
import Balance from '../components/Clients/Balance';
import CheckIn from '../components/Clients/Checkin';
import Checkout from '../components/Clients/Checkout';
import ValidateUsers from './Admin/ValidateUsers';
import CheckParkingData from './Admin/CheckParkingData';
import MapParkings from './Admin/MapParkings';
import NotifyUsers from './Func/NotifyUsers';
if (localStorage.jwtToken) {
  // Set auth token header auth
  const token = localStorage.jwtToken;
  setAuthToken(token);
  // Decode token and get user info and exp
  const decoded = jwt_decode(token);
  // Set user and isAuthenticated
  store.dispatch(setCurrentUser(decoded));
  // Check for expired token
  const currentTime = Date.now() / 1000; // to get in milliseconds
  if (decoded.exp < currentTime) {
    // Logout user
    store.dispatch(logoutUser());
    // Redirect to login
    window.location.href = './searchVehicles';
  }
}

class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Router>
          <div className='App'>
            <Navbar />

            <Switch>
              <Route exact path='/' component={SearchVehicles} />
              <Route exact path='/register' component={Register} />
              <Route exact path='/login' component={Login} />
              <Route exact path='/places' component={Places} />
              <Route exact path='/searchVehicles' component={SearchVehicles} />

              <PrivateRoute exact path='/main' component={Clients} />
              <PrivateRoute exact path='/profile' component={Profile} />
              <PrivateRoute exact path='/balance' component={Balance} />
              <PrivateRoute exact path='/checkin' component={CheckIn} />
              <PrivateRoute exact path='/checkout' component={Checkout} />
              <PrivateRoute
                exact
                path='/validateusers'
                component={ValidateUsers}
              />
              <PrivateRoute
                exact
                path='/checkParkings'
                component={CheckParkingData}
              />
              <PrivateRoute exact path='/marParkings' component={MapParkings} />
              <PrivateRoute exact path='/charts' component={Charts} />

              <PrivateRoute exact path='/notifyUsers' component={NotifyUsers} />
            </Switch>
          </div>
        </Router>
      </Provider>
    );
  }
}
export default App;
/*  /config/rolesConfig.js || /config/roles.js  */
export default {
  //role name as a key.
  admin: {
    routes: [
      {
        component: 'Charts',
        url: '/charts'
      },
      {
        component: 'MapParkings',
        url: '/marParkings'
      },
      {
        component: 'CheckParkingData',
        url: '/checkParkings'
      },
      {
        component: 'ValidateUsers',
        url: '/validateusers'
      }
    ]
  },
  employee: {
    routes: [
      {
        component: 'NotifyUsers',
        url: '/notifyUsers'
      }
    ]
  },
  client: {
    routes: [
      {
        component: 'Clients',
        url: '/main'
      },
      {
        component: 'Balance',
        url: '/balance'
      },
      {
        component: 'CheckIn',
        url: '/checkin'
      },
      {
        component: 'Checkout',
        url: '/checkout'
      }
    ]
  }
};

这是我的角色配置

这是我的私人路线:

import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import rolesConfig from './rolesConfig';

const PrivateRoute = ({ component: Component, auth, ...rest }) => (
  <Route
    {...rest}
    render={props =>
      auth.isAuthenticated === true ? (
        <Component {...props} />
      ) : (
        <Redirect to='/login' />
      )
    }
  />
);
PrivateRoute.propTypes = {
  auth: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
  auth: state.auth
});
export default connect(mapStateToProps)(PrivateRoute);

我可以提供有关如何执行此操作以及在何处映射角色配置的提示吗?

我可能会在您的配置中反转控制,即将路由映射到可以访问它的角色列表。

路由配置

import Navbar from '../components/Navbar/Navbar';
import Register from '../components/Auth/Register';
import Login from '../components/Auth/Login';
import PrivateRoute from '../components/PrivateRoute/PrivateRoute';
import Charts from '../components/Dashboard/Charts';
import Places from '../components/Places/Places';
import Clients from '../components/Clients/Clients';
import SearchVehicles from '../components/Clients/SearchVehicles';
import Profile from '../components/Clients/Profile';
import Balance from '../components/Clients/Balance';
import CheckIn from '../components/Clients/Checkin';
import Checkout from '../components/Clients/Checkout';
import ValidateUsers from './Admin/ValidateUsers';
import CheckParkingData from './Admin/CheckParkingData';
import MapParkings from './Admin/MapParkings';
import NotifyUsers from './Func/NotifyUsers';

export default {
  routes: [
    {
      component: SearchVehicles,
      url: '/',
      roles: [],
    },
    {
      component: Register,
      url: '/register',
      roles: [],
    },
    {
      component: Login,
      url: '/login',
      roles: [],
    },
    {
      component: Places,
      url: '/places',
      roles: [],
    },
    {
      component: SearchVehicles,
      url: '/searchVehicles',
      roles: [],
    },
    {
      component: Clients,
      url: "/main",
      roles: ["client"],
    },
    {
      component: Profile,
      url: "/profile",
      roles: ["client", "admin", "employee"], // Just a hunch that you'd want all authenticated roles to access
    },
    {
      component: Balance,
      url: "/balance",
      roles: ["client"],
    },
    {
      component: CheckIn,
      url: "/checkin",
      roles: ["client"]
    },
    {
      component: Checkout,
      url: "/checkout",
      roles: ["client"],
    },
    {
      component: ValidateUsers,
      url: "/validateusers",
      roles: ["admin"]
    },
    {
      component: CheckParkingData,
      url: "/checkParkings",
      roles: ["admin"]
    },
    {
      component: MapParkings,
      url: "/marParkings",
      roles: ["admin"]
    },
    {
      component: Charts,
      url: "/charts",
      roles: ["admin"]
    },
    {
      component: NotifyUsers,
      url: "/notifyUsers",
      roles: ["employee"]
    }
  ]
};

然后,您可以将其映射到App JSX 以定义您的路由, client RoutePrivateRoute任何内容的PrivateRoute ,将roles作为道具传递。

<Switch>
  {
    routesConfig.map(({ component, roles, url }) =>
      roles.length ? (
        <PrivateRoute exact path={url} component={component} roles={roles} />
      ) : (
        <Route exact path={url} component={component} />
      )
    );
  }
</Switch>

更新您的私有路由以根据您的用户可能拥有的角色检查路由角色。

私有路由.jsx

const PrivateRoute = ({ component: Component, userRoles  = [], roles = [], ...rest }) => {
  // check the route's roles to see if any match a role the user has
  const hasRole = roles.some(role => userRoles.includes(role));
  return (
    <Route
      {...rest}
      render={props =>
        hasRole ? (
          <Component {...props} />
        ) : (
          <Redirect to='/login' />
        )
      }
    />
  );
};

const mapStateToProps = state => ({
  userRoles: state.auth.roles, // having a role assumes authenticated
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM