In Angular applications, routes are the mechanism used to define the relationship between URLs and specific components displayed on the screen. They essentially map incoming URLs to specific components, allowing users to navigate between different views within the application.
Angular route guard allows us to grant or remove access to certain parts of the navigation. Another route guard, the CanDeactivate guard, enables you to prevent a user from accidentally leaving a component with unsaved changes.
To prevent unauthorized access to certain parts of our navigation, use route guards in Angular.
Client-side route guards like this are not meant to be a security feature. However, they won’t prevent a smart user from figuring out how to get to the protected routes.
Route guards in Angular can prevent users from navigating to parts of an app without authorization.
There are 4 route guards available in Angular.
To use route guards, consider using component-less routes as this facilitates guarding child routes.
To create a service for your guard, type the following command.
ng generate guard your-guard-name
In your guard class, implement the guard you want to use. The following example uses CanActivate to guard the route.
export class YourGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
// your logic goes here
}
}
Here is the step-by-step guide to creating Route Guards in Angular.
To create a new Angular project, type the following command.
ng new angularguard
While creating a new project, please enable the routing so that the app-routing.module.ts file is created.
Inside the project and create the following two components.
Type the following commands to create components.
ng g c home --skipTests=true ng g c dashboard --skipTests=true
Write the following code inside the app-routing.module.ts file.
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { DashboardComponent } from './dashboard/dashboard.component';
const routes: Routes = [
{ path: '', component: AppComponent },
{ path: 'home', component: HomeComponent},
{ path: 'dashboard', component: DashboardComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
We have defined three routes.
Edit the app.component.html file and write the following code.
<!-- app.component.html -->
<p>Angular Auth Guard Example</p>
<router-outlet></router-outlet>
The auth service is responsible for returning a boolean value. If it returns true, the user is logged in; otherwise, it is not logged in and returns false.
To create a service in Angular, type the following command.
ng g s auth --skipTests=true
The next step is to register the auth service inside the app-routing.module.ts file.
// app-routing.module.ts
import { AuthService } from './auth.service';
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: [AuthService]
})
Write the following function inside the auth.service.ts file.
// auth.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AuthService {
constructor() { }
isLoggedIn(): boolean {
return false;
}
}
To create a service for your guard, type the following command.
ng generate guard auth --skipTests=true
You can choose which type of guard you want to create, as in the following image.
I am choosing the CanActivate guard.
Your auth.guard.ts file will be created, and looks like this.
// auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return true;
}
}
The interface that a class can implement is a guard deciding if the route can be activated. If all the guards return true, navigation will continue. If any guard returns false, the navigation will be canceled.
If any guard returns the UrlTree, current navigation will be canceled, and new navigation will be kicked off to the UrlTree returned from a guard.
Import the auth.service.ts file inside this guard.
After that, we will complete the canActivate() function.
Based on whether the user is authenticated, the canActivate() function will return true or false.
Write the following code inside the auth.guard.ts file.
// auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private auth: AuthService) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (this.auth.isLoggedIn()) {
return true;
}
window.alert('You don\'t have permission to view this page');
return false;
}
}
In your routing module, use the appropriate property in your route configuration.
Add the following code inside the app-routing.module.ts file.
// app-routing.module.ts
import { AuthGuard } from './auth.guard';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'home', component: HomeComponent},
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }
];
Here, canActivate tells the router to mediate navigation to this particular route.
Let’s try to access the dashboard route.
Go to the browser and type this URL: http://localhost:4200/dashboard.
You will see something like this.
That is it. We have successfully prevented access using the Auth guard.
Let’s return true from the auth.service.ts file’s isLoggedIn() function.
// auth.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AuthService {
constructor() { }
isLoggedIn(): boolean {
return true;
}
}
We should be able to access the dashboard component, route, or page.
Let’s try one more time. Go to http://localhost:4200/dashboard.
Bingo!! You now have access to the page. See the following output.
Thanks for reading !!!
#angularroute #angular