How to implement multi role based authorization in React
Solution 1
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>
Solution 2
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
Solution 3
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 videos on Youtube
Jonas
Updated on March 09, 2020Comments
-
Jonas about 4 years
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
-
Not A Bot about 4 yearsCan you post some of the code or approach you followed to achieve the task?
-
Jonas about 4 years@NotABot actually, I have different dashboard in my application , I want to show separate dashboard for different users like admin, manager etc
-
Not A Bot about 4 yearsWhat I am asking any logic you have applied for this?
-
Jonas about 4 years@NotABot no , currently I don't implement any logic . I am stuck , I wan to ask about logic
-
Not A Bot about 4 yearsSee when you authenticate the user, then store the role of the user maybe in
localStorage
or any other storage which you are familiar with. Then before rendering the UI, just check what is the role of the user, and then render theUI
.
-
-
Jonas about 4 yearscould you please write a simple example, it will help me to save a day
-
Jonas about 4 yearsthanks for your answer , could you please guide me what
granPermission
used for ? -
Jonas about 4 yearsGreat , How I can render UI conditionally . mean I want to render separate dashboard like admin,manager
-
Mark about 4 yearsYou can use different paths for each role or you can do the same thing for component rendering. I have updated the answer. Please check again.
-
Jonas about 4 yearsone more thing, when I try to console roles={['ROLE_ADMIN']} in rolebasedRouting.jsx I am getting all these three props. I want only requested route props (roles)
-
Mark about 4 yearscan you share your code, your log and elaborate what are you trying to do
-
Jonas about 4 yearsLet us continue this discussion in chat.