For the purpose of the demonstration, we will be creating a simple Angular app that grants access to the dashboard route upon successful Login.
Step 1: Setup Project
Create an Angular Project with Angular CLI with routing flag.
Let’s also create Login and Dashboard components.
ng new routing-app --routing
ng generate component login
ng generate component dashboard
ng generate component pageNotFound
npm start
Step 2: Routes
Add route in the app-routing.module.ts file, the route object accepts a path and a component object.
Upon navigating to the mentioned path corresponding component gets rendered as shown in below example.
If you want to activate a path conditionally then you simply add canActivate to the route object and assign a Guard to it.
The Guards canActivate method executes the conditional logic and returns boolean which sets the permission for the path. More on that in step 4
app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './components/login/login.component';
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';
import { DashboardComponent } from './components/dashboard/dashboard.component';
import { AuthGuard } from './guard/auth.guard';
const routes: Routes = [
{path:"login", component : LoginComponent},
{path:"dashboard", component : DashboardComponent, canActivate : [AuthGuard]},
{path:"**", component: PageNotFoundComponent}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
You should add a router selector to the root template page i.e app.component.html but that would be already added if you are using angular CLI.
app.component.html
<router-outlet></router-outlet>
Routing is set up you can navigate to localhost:4200/login which would render the LoginComponent.
Step 3: Login Component
We create a login component that takes the user credentials and sends it to the auth service for verification.
login.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Router } from '@angular/router';
import { AuthService } from 'src/app/services/auth.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
constructor(private form: FormBuilder,
private router: Router,
private authService: AuthService) { }
message = "";
ngOnInit(): void {
}
login = this.form.group({
username: "",
password: ""
})
onSubmit() {
this.authService.authenticate(this.login.value)
if(this.authService.isAuthorised){
this.router.navigate(['/dashboard'])
this.message = this.authService.message;
}
else{
this.router.navigate(['/login'])
this.message = this.authService.message;
}
}
}
login.component.html
<div class="panel panel-default center">
<div class="panel-heading">Login</div>
<div class="panel-body">
<form [formGroup]="login" (ngSubmit)="onSubmit()" class="form-horizontal">
<div class="form-group">
<label class="control-label col-sm-2" for="pwd">Username:</label>
<div class="col-sm-10">
<input type="text" required class="form-control" placeholder="Enter username"
formControlName="username">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="pwd">Password:</label>
<div class="col-sm-10">
<input type="password" required class="form-control" placeholder="Enter password"
formControlName="password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button [disabled]="!login.valid" type="submit" class="btn btn-default">Submit</button>
</div>
<div class="col-sm-offset-2 col-sm-10">
{{message}}
</div>
</div>
</form>
</div>
</div>
Step 4 : Auth Service
Credentials taken from the login component are sent to the auth service as shown below which then verifies it and accordingly sets the isAuthoroised boolean flag in the Auth Service.
This flag is then used in the Auth Guards canActivate method to set the permissions to the route.
ng generate service services/auth
auth.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AuthService {
constructor() { }
isAuthorised = false;
message = "";
authenticate(cred){
if(cred.username === "rohit"){
if(cred.password === "abc"){
this.isAuthorised = true;
this.message = ""
}
else{
this.isAuthorised = false;
this.message = "Auth Failed"
}
}
return this.isAuthorised;
}
}
For the convenience of this demonstration, we have hardcoded the username and password.
Step 5: Auth Guard
Final step is to add auth guard, you can do that by executing below angular cli command.
ng generate guard guard/auth
It would create auth.guard.ts file. In its canActivate method you return the isAuthorised flag from the auth service.
If the user is authorized you return true which will render the Dashboard component else navigate it to login component.
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from '../services/auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService:AuthService, private router:Router){}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if(!this.authService.isAuthorised){
this.router.navigate(['/login'])
}
return true;
}
}
Well that’s it, you now know how to do authorization in Angular using Auth Guard.
You can find the source code at my GitHub repo https://github.com/thatsrohitnaik/Angular-Auth-Guard
Happy Coding !!