How to implement multi role based authorization in React

Viewed 24094

I am working on application where I have different multi role ( admin, user,manager ) I want to protect route of admin from manager and general user also render UI based on user role . I tried but I am failed could someone please help me how to achieve my goal . Example will be appreciated

Thanks

3 Answers

Please beware that this is not an optimal solution and only meant to give you some ideas.

Create a file RoleBasedRouting.jsx

function RoleBasedRouting({
  component: Component, roles, ...rest
}) {
  return (
    <>
      { grantPermission(roles) && (
      <Route
        {...rest}
        render={(props) => (
          <>
            <Component {...props} />
          </>
        )}
      />
      )}
      {
        !grantPermission(roles) && (
          <Route
            render={() => (
              <>
                <Unauthorized /> // Unauthorized Page View (skippable)
              </>
            )}
          />
        )
      }
    </>
  );
}

Use it in your Router like this -

<Switch>
     <RoleBasedRouting exact path="/admin" component={AdminPage} roles={['ROLE_ADMIN']} />
     <RoleBasedRouting exact path="/user" component={UserPage} roles={['ROLE_USER']} />
     <RoleBasedRouting exact path="/manager" component={ManagerPage} roles={['ROLE_Manager']} />
     ...............
</Switch>

In grantPermission function, check if the logged in user has the required roles. Sample -

export const grantPermission = (requestedRoles) => {
  const permittedRoles =  JSON.parse(localStorage.getItem('userRoles'));
 // in case of multiple roles, if one of the permittedRoles is present in requestedRoles, return true;
  return false;
};

To render UI conditionally, you can do basically the same thing. Write a component UnlockAccess -

const UnlockAccess = ({ children, request }) => {
  const permission = grantPermission(request); // request = ['ROLE_ADMIN'] / ['ROLE_USER'] / ['ROLE_MANAGER']
  return (
    <>
      {permission && children}
    </>
  );
};

Now, Use UnlockAccess component in the Dashboard page like this -

<Dashboard>
    <UnlockAccess request={['ROLE_ADMIN']}>
         <>
              {/*Write code/components for Admin Dashboard*/}
         </>                    
    </UnlockAccess>
    <UnlockAccess request={['ROLE_USER']}>
         <>
              {/*Write code/components for User Dashboard*/}
         </>                    
    </UnlockAccess>
    <UnlockAccess request={['ROLE_MANAGER']}>
         <>
              {/*Write code/components for Manager Dashboard*/}
         </>                    
    </UnlockAccess>
</Dashboard>

You should create different route components specifically for all roles, for example, AdminRoute, UserRoute, etc and in these components, you can check the weather login person is admin or a normal user.

or create a general route component and pass role and path there as props

You can use a HOC to check if the user accessing the route is allowed to access, i.e. if user is admin who is trying to access the admin dashboard is admin. If not then can redirect him to wherever you like.

export default function withAuth(WrappedComponent) {


const auth = (props) => {
    return (
        localStorage.getItem("userRole") === "admin" ?
        <WrappedComponent {...props} /> :
        <Redirect to = {{ 
            pathname: "/protected/login"
        }} />
    )
}

return auth;
}

Or you can maintain a features array in localStorage with features you wanna give access to your user.

Related