What is the best way to conditionally render routes in react-router based on user role. I have a case where not all roles have permission to view certain routes. And also I need to deal with subroutes. So if one of main routes is something like /posts I want only admin and student to access that route and its subroutes (posts/today for example). I am using react-router version 5.3.2.
Asked
Active
Viewed 1.9k times
5
-
1Define Roles and Permissions at the backend. After login (authentication), control the routes based on permissions (authorization). Create a component like `Check` which would check if current user is having enough permissions to see this page or not. Google for keywords "authorization" in general and in react app. Maybe you will find some code example. Before you code, it is important to understand it. So, if you focus on understanding, you can write code in your own way. – Ajeet Shah Jan 17 '22 at 18:37
2 Answers
6
I has a similar issue with react-router-dom v6, but you can tweak it to your benefits
First create a source of truth wheither a user can or can't access some route, for roles based auth I'd think of a hook like
export function useUserRoles() {
// some logic or api call to get the roles
// for demonstration purposes it's just hard coded
const userRoles: Array<typeof UserRoles[number]> = ['admin', 'root'];
// return the current user roles
return userRoles;
}
Then we make a component that can decide using that hook weither to render the route or redirect to login(or some page)
export function RolesAuthRoute({ children, roles }: { children: ReactNode, roles: Array<typeof UserRoles[number]> }) {
const userRoles = useUserRoles();
const canAccess = userRoles.some(userRole => roles.includes(userRole));
if (canAccess)
return (
<Fragment>
{children}
</Fragment>
);
return (<Navigate to="/dashboard/login" />);
}
then the route defined wraps that component to act as a guard that decide if you can or can't access that route
<Route
path="users"
element={
<Suspense fallback={<ProjectLayoutLoader />}>
<RolesAuthRoute roles={['admin']}>
<ProjectUsersPage />
</RolesAuthRoute>
</Suspense>
} />

Louay Al-osh
- 3,177
- 15
- 28
1
i have two role "parent" and "manager" and i write this code and work it for me:
function App(props) {
return (
<div className="App ">
<Routes>
<Route exact path="/" element={<Home />} />
<Route exact path="/" element={<ProtectedRoute />}>
<Route exact path="/admin" element={<StudentLists />} />
<Route exact path="/student_pk_api/:id" element={<IdFilter />} />
<Route exact path="/absentes" element={<AbsentStu />} />
<Route exact path="/students_by_field_and_level_:grade_api/:studyfield_code" element={<FieldGradeFilter />} />
<Route exact path="/absent_yesterday_api" element={<YesterdayAbs />} />
<Route exact path="/absent_today_api" element={<TodayAbs />} />
</Route>
<Route exact path="/" element={<ProtectedUserRoute />}>
<Route exact path="/users" element={<SchoolDit />} />
</Route>
</Routes>
</div>
);
}
for cheking roles i write two function:
for manager role:
const ProtectedRoute = () => {
const [manager, setmaneger] = useState(localStorage.getItem("role")==="manager"?true:null);
return manager ? <Outlet /> : <Navigate to="/" />;
}
export default ProtectedRoute
for parent role:
const ProtectedUserRoute = () => {
const [parent, setParent] = useState(localStorage.getItem("role")==="parent"?true:null);
return parent ? <Outlet /> : <Navigate to="/" />;
}
export default ProtectedUserRoute

maede
- 11
- 2