Angular 7 Login With Session Authentication Using React Form

In this article, you will learn about Angular 7 login with session authentication using the React form.

Introduction

 
In this article, we are going to manage the login process. We will check whether the user is logged in or not, and will block the route if the user is not authenticated.
 
While walking through this article, we will cover the below Angular concepts.
  • Angular Routing module
    Manage Angular route as user authentication permission.

  • Angular Auth Guard
    This Angular feature is helpful for handling authentication. This is an interface which tells the router whether or not it should allow navigation to a requested route. Here, in this example, we are using the 'canActivate' guard type. For more information about Angular guard, you can visit here.

  • Angular localStorage
    There are three ways to store data into client-side in Angular application 
  1. Memory 
  2. Session storage 
  3. Local Storage. 
Here, we are using the localStorage which stores data into the client browser. It is supported only in a modern browser. In this, data will remain stored if the browser is closed or reopened while in session storage, the data will be lost when the tab is closed. It's simple to use and the syntax of the localStorage is also easy. It allows ~10mb data to be saved in the browser.
 
Now, let's implement.
 
Create a new Angular project using the below command.
 
ng new AngularRegistration
 
Here, I used bootstrap in this application. To install bootstrap in an application, you can run the below command inside the terminal.
 
npm install bootstrap
 
After installation, add the below line in the src/styles.css file.
  1. @import '~bootstrap/dist/css/bootstrap.min.css';  
Now, create two components as Login and Dashboard.
Create one service named as auth
Create a new login interface
Create a new guard named as auth by using the below command lines.
Here, Angular guard means it is the Angular route guard which can tell the router whether or not it should allow navigation to a requested route.
 
ng g component login
ng g component dashboard
ng g service services/auth // create service in services named folder
ng g interface interfaces/login // create a new interface in interfaces named folder.
ng g guard guards/auth /// create new guard in guards named folder
 
Add two properties in the Login interfaces.
 
Login.ts
  1. export class ILogin {      
  2.    userid: string;    
  3.    password: string;    
  4. }   
Now, go to the guards/Auth.guard.ts file. Import the ‘canActivate’ interface from ‘@angular/router’ package.
 
Auth.guard.ts
 
Implement the canActive() method inside this file.
  1. import { Injectable } from '@angular/core';      
  2. import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivate, Router } from '@angular/router';      
  3. import { Observable } from 'rxjs';      
  4. @Injectable({      
  5.    providedIn: 'root'      
  6. })      
  7. export class AuthGuard implements CanActivate {      
  8.    constructor(private router: Router) { }      
  9.    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {      
  10.       if (this.isLoggedIn()) {      
  11.       return true;      
  12.       }      
  13.       // navigate to login page as user is not authenticated      
  14.    this.router.navigate(['/login']);      
  15. return false;      
  16. }      
  17. public isLoggedIn(): boolean {      
  18.    let status = false;      
  19.    if (localStorage.getItem('isLoggedIn') == "true") {      
  20.       status = true;      
  21.    }    
  22.    else {      
  23.       status = false;      
  24.       }      
  25.    return status;      
  26.    }    
  27. }    
Now, in app.module.ts file, import the AuthGuard module.
  1. import { AuthGuard } from './guards/auth.guard'
Add AuthGuard in Providers.
 
Then, import ReactiveFormsModule and FormsModule in this file from @angular/forms package.
 
So, now, our app.module.ts file will look like this.
  1. import { BrowserModule } from '@angular/platform-browser';    
  2. import { NgModule } from '@angular/core';    
  3. import { AppRoutingModule } from './app-routing.module';    
  4. import { AppComponent } from './app.component';    
  5. import { LoginComponent } from './login/login.component';    
  6. import { DashboardComponent } from './dashboard/dashboard.component';    
  7. import { AuthGuard } from './guards/auth.guard';    
  8. import { FormsModule, ReactiveFormsModule } from '@angular/forms';    
  9.     
  10. @NgModule({    
  11.    declarations: [    
  12.    AppComponent,    
  13.    LoginComponent,    
  14.    DashboardComponent    
  15. ],    
  16. imports: [    
  17.    BrowserModule,    
  18.    AppRoutingModule,    
  19.    FormsModule,    
  20.    ReactiveFormsModule    
  21. ],    
  22.    providers: [AuthGuard],    
  23.    bootstrap: [AppComponent]    
  24. })    
  25. export class AppModule { }    
Now, go to the app-routing.modue.ts file and add login and dashboard routes inside it. Here, add the ‘canActivate’ attribute to check user authentication. If the user is not authorized, then it will redirect to the login page. 
  1. import { NgModule } from '@angular/core';  
  2. import { Routes, RouterModule } from '@angular/router';  
  3. import { LoginComponent } from './login/login.component';  
  4. import { DashboardComponent } from './dashboard/dashboard.component';  
  5.   
  6. const routes: Routes = [  
  7.    { path: 'login', component: LoginComponent },  
  8.    { path: 'dashboard', component: DashboardComponent, canActivate : [AuthGuard] }  
  9. ];  
  10.   
  11. @NgModule({  
  12.    imports: [RouterModule.forRoot(routes)],  
  13.    exports: [RouterModule]  
  14. })  
  15. export class AppRoutingModule { }  
Put the below HTML code inside the app.component.html file.
  1. <!--The content below is only a placeholder and can be replaced.-->  
  2. <div class="container">  
  3.     <!-- Static navbar -->  
  4.     <nav class="navbar navbar-inverse">  
  5.         <div class="container-fluid">  
  6.             <div class="navbar-header">  
  7.                 <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">  
  8.                     <span class="sr-only">Toggle navigation</span>  
  9.                     <span class="icon-bar"></span>  
  10.                     <span class="icon-bar"></span>  
  11.                     <span class="icon-bar"></span>  
  12.                 </button>  
  13.                 <a class="navbar-brand" href="#">Angular Registration</a>  
  14.             </div>  
  15.             <div id="navbar" class="navbar-collapse collapse">  
  16.                 <ul class="nav navbar-nav">  
  17.                     <li routerLinkActive="active">  
  18.                         <a routerLink="/login">Login</a>  
  19.                     </li>  
  20.                     <li routerLinkActive="active">  
  21.                         <a routerLink="/dashboard">Dashboard</a>  
  22.                     </li>  
  23.                 </ul>  
  24.             </div>  
  25.             <!--/.nav-collapse -->  
  26.         </div>  
  27.         <!--/.container-fluid -->  
  28.     </nav>  
  29.     <router-outlet></router-outlet>  
  30. </div>   
Here, routerLink contains the path of the URL and routeLinkActive adds class active to the selected menu.  <router-outlet> will decide which View to be displayed as per the route URL.
 
In auth.service.ts file, import ILogin interface.
  1. import { ILogin } from 'src/app/interfaces/login';   
Add Logout() method inside this service class.
  1. import { Injectable } from '@angular/core';    
  2. import { ILogin } from '../interfaces/login';    
  3.     
  4. @Injectable({    
  5.    providedIn: 'root'    
  6. })    
  7. export class AuthService {    
  8.    constructor() { }    
  9.    logout() :void {    
  10.    localStorage.setItem('isLoggedIn','false');    
  11.    localStorage.removeItem('token');    
  12.    }    
  13. }   
Now, go to the login.component.ts file and import Router from @angular/router package. Import login interface, Import AuthService inside this file.
  1. import { Router } from '@angular/router';  
  2. import { ILogin } from 'src/app/interfaces/login';  
  3. import { AuthService } from '../services/auth.service'  
Also, import FormBuilder,FormGroup,Validators from @angular/forms package.
  1. import { FormBuilder, FormGroup, Validators } from '@angular/forms';  
Create three instances - router, service, and formBuilder inside the constructor.
  1. constructor(  
  2.    private formBuilder : FormBuilder,  
  3.    private router : Router,  
  4.    private authService : AuthService  
  5. ) { }  
Create a new variable modal as ILogin interface and set default parameters.
  1. model: ILogin = { userid: "admnin", password: "admin@123" }  
 
Create loginForm variable as type FormGroup. Message as type string and returnURL as type of string.
  1. loginForm: FormGroup;  
  2. message: string;  
  3. returnUrl: string;  
Inside ngOnInit() metod, create new formGroup and add required validation on both properties.
  1. ngOnInit() {  
  2.    this.loginForm = this.formBuilder.group({  
  3.       userid: ['', Validators.required],  
  4.       password: ['', Validators.required]  
  5.    });  
  6. this.returnUrl = '/dashboard';  
  7. this.authService.logout();  
  8. }  
Add get method for easy form access.
  1. // convenience getter for easy access to form fields  
  2.   
  3. get f() { return this.loginForm.controls; }  
Add Login() method inside this class.
  1. login() {  
  2.   
  3. // stop here if form is invalid  
  4. if (this.loginForm.invalid) {  
  5.    return;  
  6. }  
  7. else {  
  8.    if (this.f.userid.value == this.model.userid && this.f.password.value == this.model.password) {  
  9.       console.log("Login successful");  
  10.       //this.authService.authLogin(this.model);  
  11.       localStorage.setItem('isLoggedIn'"true");  
  12.       localStorage.setItem('token'this.f.userid.value);  
  13.       this.router.navigate([this.returnUrl]);  
  14.    }  
  15. else {  
  16.    this.message = "Please check your userid and password";  
  17.    }  
  18.   }  
  19. }  
So, login.component.ts will look like this,
  1. import { Component, OnInit } from '@angular/core';  
  2. import { Router } from '@angular/router';  
  3. import { ILogin } from 'src/app/interfaces/login';  
  4. import { AuthService } from '../services/auth.service'  
  5. import { FormBuilder, FormGroup, Validators } from '@angular/forms';  
  6.   
  7. @Component({  
  8.    selector: 'app-login',  
  9.    templateUrl: './login.component.html',  
  10.    styleUrls: ['./login.component.css']  
  11.    })  
  12. export class LoginComponent implements OnInit {  
  13.   
  14.    model: ILogin = { userid: "admnin", password: "admin@123" }  
  15.    loginForm: FormGroup;  
  16.    message: string;  
  17.    returnUrl: string;  
  18.    constructor(  
  19.       private formBuilder: FormBuilder,  
  20.       private router: Router,  
  21.       private authService: AuthService  
  22.    ) { }  
  23.   
  24.    ngOnInit() {  
  25.       this.loginForm = this.formBuilder.group({  
  26.          userid: ['', Validators.required],  
  27.          password: ['', Validators.required]  
  28.       });  
  29.    this.returnUrl = '/dashboard';  
  30.    this.authService.logout();  
  31.    }  
  32.   
  33. // convenience getter for easy access to form fields  
  34. get f() { return this.loginForm.controls; }  
  35.   
  36.   
  37. login() {  
  38.   
  39.    // stop here if form is invalid  
  40.    if (this.loginForm.invalid) {  
  41.       return;  
  42.    }  
  43.    else {  
  44.       if (this.f.userid.value == this.model.userid && this.f.password.value == this.model.password) {  
  45.       console.log("Login successful");  
  46.       //this.authService.authLogin(this.model);  
  47.       localStorage.setItem('isLoggedIn'"true");  
  48.       localStorage.setItem('token'this.f.userid.value);  
  49.       this.router.navigate([this.returnUrl]);  
  50.       }  
  51.    else {  
  52.       this.message = "Please check your userid and password";  
  53.       }  
  54.      }  
  55.   }  
  56.   
  57. }  
Login.component.html
  1. <div class="container">    
  2.     <div class="col-md-6 col-md-offset-3 loginBox">    
  3.         <h3>Log In</h3>    
  4.         <p *ngIf="message" class="text-center error">{{message}}</p>    
  5.       <form [formGroup]="loginForm" (ngSubmit)="login()">    
  6.           <div class="form-group clearfix" [ngClass]="{ 'has-error': submitted && f.userid.errors }">    
  7.               <label for="userid" class="col-md-3 col-sm-5 col-xs-12">Userid</label>    
  8.               <div class="col-md-9 col-sm-7 col-xs-12">    
  9.                   <input type="text" class="form-control" formControlName="userid" />    
  10.                   <div *ngIf="submitted && f.userid.errors" class="help-block">    
  11.                         <div *ngIf="f.userid.errors.required">Userid is required</div>    
  12.                   </div>    
  13.               </div>    
  14.           </div>    
  15.           <div class="form-group clearfix" [ngClass]="{ 'has-error': submitted && f.password.errors }">    
  16.             <label for="password" class="col-md-3 col-sm-5 col-xs-12">Password</label>    
  17.             <div class="col-md-9 col-sm-7 col-xs-12">    
  18.                 <input type="password" class="form-control" formControlName="password"/>    
  19.                 <div *ngIf="submitted && f.password.errors" class="help-block">    
  20.                         <div *ngIf="f.password.errors.required">Password is required</div>    
  21.                 </div>    
  22.             </div>    
  23.           </div>    
  24.           <div class="col-xs-12 form-group text-right">    
  25.             <button class="btn btn-success" type="submit">Login</button>    
  26.           </div>    
  27.       </form>    
  28.     </div>    
  29. </div>   
Dashboard.component.ts
 
Inside this ts file, implement logout() method. If User is not authenticated then this page will not be accessible and user redirect to the login page.
  1. import { Component, OnInit } from '@angular/core';  
  2. import { Router } from '@angular/router';  
  3. import { AuthService } from '../services/auth.service';  
  4.   
  5. @Component({  
  6.   selector: 'app-dashboard',  
  7.   templateUrl: './dashboard.component.html',  
  8.   styleUrls: ['./dashboard.component.css']  
  9. })  
  10. export class DashboardComponent implements OnInit {  
  11.   
  12.   id: string;  
  13.   
  14.   constructor(private router: Router, private authService: AuthService) { }  
  15.   
  16.   ngOnInit() {  
  17.     this.id = localStorage.getItem('token');  
  18.     //console.log(this.id);  
  19.   }  
  20.   
  21.   logout() {  
  22.     console.log('logout');  
  23.     this.authService.logout();  
  24.     this.router.navigate(['/login']);  
  25.   }  
  26.   
  27. }  
Dashboard.component.html
 
This page will display if the user is authorized and display the logged user's id inside {{id}}. 
  1. <div class="container">    
  2.   <div class="col-md-6 col-md-offset-3 loginBox">    
  3.       Welcome,  {{id}}    
  4.       <a href="javascript:void(0);" (click)="logout()">Logout</a>    
  5.   </div>    
  6. </div>   

Conclusion

 
By using this approach, we can manage user authentication, route access, and the session variable. We can use this Angular Guard approach to prevent requested navigation if the user is not authenticated.
 
Happy coding!