Two question I often see posted about Ionic apps are
1) how do I handle authentication ( protected routes ) and
2) How do I handle child routes when using Tabs in Ionic.
So I am going to try to present a simple bare bones solution that addresses both problems with the code I have below. I have only included the code snippets that are essential to address the issues listed above, but the complete source code is available here: ionicv4-tabs-with-detail
This example code is based on v4 of Ionic Framework
Protected Routes
To have protected routes you need to be able to determine the logged in state of the user. To keep things as simple as possible, we have created an AuthenticationService that has a method to set the state as true or false and a method to get the current logged in state.
Next we create a new class AuthGuardService which implements the CanActivate interface.
In this example, all we are doing is calling the AuthenticationService to see if the user is authenticate or not, if the used is not authenticated, then we are redirecting the user to the route defined by the path /login. We are doing that by constructing a UrlTree object and returning that since we can return a boolean, Promise or UrlTree from the function according to the CanActivate documentation
import{Injectable}from'@angular/core';import{CanActivate,ActivatedRoute,Router}from'@angular/router';import{AuthenticationService}from'./authentication.service';@Injectable({providedIn:'root'})exportclassAuthGuardServiceimplementsCanActivate{constructor(privateauth:AuthenticationService,privaterouter:Router){}canActivate():boolean{letvalue=this.auth.isAuthenticated()if (!value){// initially was just redirecting here, but following the// documentation I updated code to return a UrlTree// this.router.navigateByUrl("/login", { skipLocationChange: true })returnthis.router.parseUrl("/login");}returnvalue}}
Now that we have our AuthenticationService to tell us the state of the user, our AuthGuardService to be used to check before rendering a route; we are ready to update the app-routing.module.
See below where we add the AuthGuardService to the default route so that when the app is first launched, the users authentication state will be verified, otherwise it will redirect to the LoginPageModule
import{NgModule}from'@angular/core';import{Routes,RouterModule}from'@angular/router';import{AuthGuardService}from'../services/authGuard.service';// in the routes that need to be protected or the user// has to be authenticated, we add the AuthGuardServiceconstroutes:Routes=[{path:'',canActivate:[AuthGuardService],loadChildren:'./tabs/tabs.module#TabsPageModule'},{path:'login',loadChildren:'./public/auth/login/login.module#LoginPageModule'},];@NgModule({imports:[RouterModule.forRoot(routes)],exports:[RouterModule]})exportclassAppRoutingModule{}
Child Routes In Tabs
The tabs router module has some magic here to handle the default route and also to properly handle child routes to properly manage the navigation stack for each tab.
The first component rendered is the TabsPage, but as you can see that page has child modules, the first one being the HomePageModule which will render the HomePage.
(1) at the bottom of the code segment below we show how we handle the default route for the tab module, redirecting it to the home tab.
Handling the child route of a tab, or rendering a detail page is demonstrated with the second route definition under the home path. We have defined the path detail which we access using the full path of /tabs/home/detail
(2) This will load the DetailPageModule which will in turn load the DetailPage since it is the default route in the DetailPageModule.
constroutes:Routes=[{path:"tabs",component:TabsPage,children:[{path:"home",children:[{path:"",loadChildren:"./../home/home.module#HomePageModule"},// (2) loads detail page, pushing it on the navigation stack of // the home tab{path:"detail",loadChildren:"./../detail/detail.module#DetailPageModule"}]},{path:"about",children:[{path:"",loadChildren:"./../about/about.module#AboutPageModule"}]},{path:"contact",children:[{path:"",loadChildren:"./../contact/contact.module#ContactPageModule"}]}]},// (1) the default route of this module is the home tab so that tab is// displayed when directed here from the top level router module.{path:"",redirectTo:"/tabs/home",pathMatch:"full"}];
Handling the Routes in the Application
Log In
For logging in to the application, we have included the following code in the login.page.ts file. The application will first call the injected AuthenticationService to set the logged in state, and then it will navigate to the default route of the application
For logging out of the application, we have included the following code in the home.page.ts file. The application will first call the injected AuthenticationService to set the logged in state, and then it will navigate to the login route of the application.
We put an AuthGuard on the module that provides access to all of the member related pages and functionality. The login page has no gaurd so it can be freely accessed. See more information on Route Guards in the angular.io documentation