React Router v6 has plenty of new changes if you aren’t familiar with reach/router before. Let’s look at how we can create a Private Route in this article with an example.
We’ll create a “Private Route” that will be accessible only who have authorization and necessary permission.
This example covers the below scenarios;
* Without logged in, the user can’t access the pages that require authorization.
* The user can’t access the pages that don’t have permission even if logged in.
* Without logged in, the user can’t make an authenticated request.
In this example, I’ve defined two different roles. The users who have the ”Admin” role can access all pages. On the other hand, the users who have the “User” role only access public pages and “Users” pages.
pages/Home.tsx ← All users can access
pages/Dashboard.tsx ← The users with "Admin" role can access
pages/Users.tsx ← The users with "User" or "Admin" role can access
pages/AccessDenied ← Authenticated users that don't have permission will be redirected to this page
pages/NotFound ← If the user try to navigate a page that doesn't exist will be redirected to this page
PrivateRoute with React Router v6
In the last lines, we create a wrapper component extending the Route component of react-router. With “…rest” prop we’re passing Route’s props to PrivateRoute.
We’re checking is user authenticated with “isAuthenticated” variable and is user permission to view this page with “userHasRequiredRole” variable. If these conditions do not match, we’re redirecting the user to “/” root.
Now, you can use the PrivateRoute component under Routes like below:
Additionally, I’ve used “RTK Query” to manage requests:
If there is a token in store we’re adding this token to the header. If the user is not logged in there will be no token in store so, protected requests will fail. (In this demo msw.js used to back-end requests)
Lastly, let’s see how login and logout reducers look like:
When a login request is successfully fulfilled we’re storing response to the state. In the logout reducer, we’re clearing the store.