React Route Guard
Based on react-router-dom
with route guard functionality on top of it. It makes it easier to control permissions and roles on a route.
Requirements
- Node <=7.1
Install
yarn add react-route-guard
You don't need to install @types/react-route-guard
, as it's written in TypeScript and the npm module already has index.d.ts
there.
Concept
-
SecureRoute
<SecureRoute>
works like same way as<Route
> and therefore you can use it in the exact same way. To enable theRouteGuard
features pass in extra props (see below). SecureRoute will then perform the following tasks:-
No DOM component will be created before
<SecureRoute>
has finished its check -
When the
<SecureRoute>
component has mounted, it will runRouteGuard.shouldRoute()
. When this function is complete,SecureRoute
will update the state.RouteGuard.shouldRoute()
can synchronously return aboolean
or asynchronously return aPromise<boolean>
orObservable<boolean>
-
SecureRoute.render()
will only render the route component when route guard has finished, and will render<Redirect to={this.props.redirectToPathWhenFail | '/'} />
if the route guard check fails
-
<Router> <Switch> <SecureRoute path='/about' component=AboutComponent /> <SecureRoute path='/users' component=UserListComponent routeGuard=UserRouteGuard redirectToPathWhenFail='/login' /> <SecureRoute path='/users/:id' component=UserEditComponent routeGuard=UserRouteGuard redirectToPathWhenFail='/login' /> <Route /> <Route /> </Switch> </Router>
-
RouteGuard
RouteGuard
is responsible for telling<SecureRoute>
whether to enter that route or not.shouldRoute()
is the key to making that happen, this method must return a boolean value in sync mode or return aPromise<boolean>
orObservable<boolean>
in async mode. Before theRouteGuard
finished, no child components will be rendered, which means no real routing will be executed.RouteGuard
will stop unauthorized users seeing a route altogether.
/*** @export* @interface RouteGuard*/
Usage
Here are some shouldRoute()
example for different situation:
- Sync example
: RouteGuardResultType // Sync API call here, and the final return value must be `map` to `boolean` if not const resultFromSyncApiCall = true; return resultFromSyncApiCall
- Async Promise example
async : RouteGuardResultType // You can use a `Promise` to get // the final boolean result return { // Simulate call backend API for checking the authentication and even authorization };
- Async Promise example with multiple promises
async : RouteGuardResultType // You can use `Promise.all()` for getting // the final boolean result to based on multiple requirements const results = await Promiseall loginUserPromise getUserPermissionPromise getUserDashboardPromise return results0user ? true : false
- Async Observable example
: RouteGuardResultType // If use Redux, we can dispatch an action to tell UI that `RouteGuard` is running. // This is useful for displaying loading indicators before the `shouldRoute` is complete appStore // Simulate a call to an API to grab the user and permissions return Observable // If use Redux, then dispatch an action to tell UI that `RouteGuard` is done, can hide // the loading spin right now.
- Async real world example
: RouteGuardResultType appStore // Get the entire state to check whether the user is already logged in or not const appState: AppState = appStore as AppState; // Already logged in, pass instantly if appStateauthloginUser && !appStateauthloginError || appStateauthloginError === '' // We can call any BackEnd APIs to rebuild the entire app state that are needed for the // routed component to be rendered correctly // // Passed return true else // Say for instance a user just opened a URL in a new tab, then we can try to load some // cookie or call some API to load user info. If the API responds successfully, // then the check has passed. From here we rebuild the entire // app state for the routed component if needed return UserService