简体   繁体   中英

Dynamic Role Based Routing (React-Router)

I am building an e-commerce related product and there are two types of users (customer & seller). Both types of user have their own homepage (totally different to each other). Now I want to route / on customer homepage if customer is logged-in or to seller homepage if seller account is logged-in. Otherwise it should route to landing page. How can I achieve this feature using react-router and this boilerplate ?

I tried to do something as follows (but it didn't work):

{
      path: '/',
      name: 'home',
      getComponent(nextState, cb) {
        let HomePagePath = 'containers/HomePage';
        if (customerLoggedIn) {
            HomePagePath = 'containers/CustomerHomePage';
       }
        const importModules = Promise.all([
          import(HomePagePath),
        ]);

        const renderRoute = loadModule(cb);

        importModules.then(([component]) => {
          renderRoute(component);
        });

        importModules.catch(errorLoading);
      },
    }, 

I'm using React Boilerplate to do something similar. Here's the gist of it:

  1. Define an onEnter function in routes.js

    onEnter: redirectToLogin, path: '/account', name: 'account', getComponent(nextState, cb) { ...

  2. Import function in routes.js

    export default function createRoutes(store) { // Create reusable async injectors using getHooks factory const { injectSagas, redirectToLogin, redirectToDashboard } = getHooks(store);

  3. Create your redirect function in app/utils/hooks.js . This is where you'd redirect based on user role.

    export function redirectToLogin(store) { // set pathname to enable redirect setPath(); return (nextState, replace) => { if (!user(store)) { replace({ pathname: '/', state: { nextPathname: nextState.location.pathname } }); } else { if (user(store).account_status === 'closed') { replace({ pathname: '/closedaccount', state: { nextPathname: nextState.location.pathname } }); } } }; }

  4. Export redirect function from app/utils/hooks.js

    export function getHooks(store) { return { injectReducer: injectAsyncReducer(store), injectSagas: injectAsyncSagas(store), redirectToLogin: redirectToLogin(store),

I found an article here , the gist of which i am writing here. You can add a prop to you component like so

<Route path="/" component={App}>

//BOD routes
<Route authorisedUsers={['KR']} path="/home" component={HomeContainer} />

//HR routes
<Route authorisedUsers={['HR']} path="/hrhome" component={HRDashboardContainer} />

//common routes    
<Route authorisedUsers={['KR', 'HR']} path="/notes" component={NotesContainer} />

and then add the following code in your component, that renders on path='/'

Role based routing react redux
componentDidUpdate() {
  const { 
      children,  //Component to be rendered (HomeContainer if route = '/home')
      pathname: {location},  //location.pathname gives us the current url user is trying to hit. (with react router)
      profileId, //profileId required by profile page common to all user journeys.
      role } = this.props; 
  this.reRoute(role, this.props.children, location.pathname, ProfileId)
}

decideRoute(role, ProfileId) { //decide routes based on role
  if(role==='HR')
    return 'hrhome';
  else if(role==='KR')
    return 'home';
  else if(role==='USER'&&ProfileId)
    return 'profile/'+ProfileId;
  else
  return '/error';
}

isAuthorised(authorisedUsers, role) {
  return _.includes(authorisedUsers, role)
}

reRoute(role, children, path, ProfileId) {
  if(role===null && path!=='/') // user hit a different path without being authenticated first
  {
    hashHistory.replace('/');  //this is where we implemented login
    return;
  }
  let route = this.decideRoute(role, ProfileId)  //if role has already been fetched from the backend, use it to decide the landing page for each role.
  if(children)  // if we already are on one of the user journey screens ...
  {
    const authorisedUsers = children.props.route.authorisedUsers 
    if(!this.isAuthorised(authorisedUsers,role)) //... and the user is not allowed to view this page...
    hashHistory.replace(`/${route}/`);  //... redirect him to the home page corresponding to his role.
  }
  else
  hashHistory.replace(`/${route}/`);  // if the user has just logged in(still on / page or login page), and we know his role, redirect him to his home page.
}//if none of these holds true, user is allowed to go ahead and view the page

This essentially adds a gateway check that would work on all your containers and will direct you based on your role. Also, it wont allow you access if you somehow hit the wrong url.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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