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 moduleManage Angular route as user authentication permission.
- Angular Auth GuardThis 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 localStorageThere are three ways to store data into client-side in Angular application
- Memory
- Session storage
- Local Storage.
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.
- @import '~bootstrap/dist/css/bootstrap.min.css';
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
- export class ILogin {
- userid: string;
- password: string;
- }
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.
- import { Injectable } from '@angular/core';
- import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivate, Router } from '@angular/router';
- import { Observable } from 'rxjs';
- @Injectable({
- providedIn: 'root'
- })
- export class AuthGuard implements CanActivate {
- constructor(private router: Router) { }
- canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
- if (this.isLoggedIn()) {
- return true;
- }
- // navigate to login page as user is not authenticated
- this.router.navigate(['/login']);
- return false;
- }
- public isLoggedIn(): boolean {
- let status = false;
- if (localStorage.getItem('isLoggedIn') == "true") {
- status = true;
- }
- else {
- status = false;
- }
- return status;
- }
- }
Now, in app.module.ts file, import the AuthGuard module.
- 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.
- import { BrowserModule } from '@angular/platform-browser';
- import { NgModule } from '@angular/core';
- import { AppRoutingModule } from './app-routing.module';
- import { AppComponent } from './app.component';
- import { LoginComponent } from './login/login.component';
- import { DashboardComponent } from './dashboard/dashboard.component';
- import { AuthGuard } from './guards/auth.guard';
- import { FormsModule, ReactiveFormsModule } from '@angular/forms';
- @NgModule({
- declarations: [
- AppComponent,
- LoginComponent,
- DashboardComponent
- ],
- imports: [
- BrowserModule,
- AppRoutingModule,
- FormsModule,
- ReactiveFormsModule
- ],
- providers: [AuthGuard],
- bootstrap: [AppComponent]
- })
- 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.
- import { NgModule } from '@angular/core';
- import { Routes, RouterModule } from '@angular/router';
- import { LoginComponent } from './login/login.component';
- import { DashboardComponent } from './dashboard/dashboard.component';
- const routes: Routes = [
- { path: 'login', component: LoginComponent },
- { path: 'dashboard', component: DashboardComponent, canActivate : [AuthGuard] }
- ];
- @NgModule({
- imports: [RouterModule.forRoot(routes)],
- exports: [RouterModule]
- })
- export class AppRoutingModule { }
Put the below HTML code inside the app.component.html file.
- <!--The content below is only a placeholder and can be replaced.-->
- <div class="container">
- <!-- Static navbar -->
- <nav class="navbar navbar-inverse">
- <div class="container-fluid">
- <div class="navbar-header">
- <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
- <span class="sr-only">Toggle navigation</span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- <a class="navbar-brand" href="#">Angular Registration</a>
- </div>
- <div id="navbar" class="navbar-collapse collapse">
- <ul class="nav navbar-nav">
- <li routerLinkActive="active">
- <a routerLink="/login">Login</a>
- </li>
- <li routerLinkActive="active">
- <a routerLink="/dashboard">Dashboard</a>
- </li>
- </ul>
- </div>
- <!--/.nav-collapse -->
- </div>
- <!--/.container-fluid -->
- </nav>
- <router-outlet></router-outlet>
- </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.
- import { ILogin } from 'src/app/interfaces/login';
Add Logout() method inside this service class.
- import { Injectable } from '@angular/core';
- import { ILogin } from '../interfaces/login';
- @Injectable({
- providedIn: 'root'
- })
- export class AuthService {
- constructor() { }
- logout() :void {
- localStorage.setItem('isLoggedIn','false');
- localStorage.removeItem('token');
- }
- }
Now, go to the login.component.ts file and import Router from @angular/router package. Import login interface, Import AuthService inside this file.
- import { Router } from '@angular/router';
- import { ILogin } from 'src/app/interfaces/login';
- import { AuthService } from '../services/auth.service'
Also, import FormBuilder,FormGroup,Validators from @angular/forms package.
- import { FormBuilder, FormGroup, Validators } from '@angular/forms';
Create three instances - router, service, and formBuilder inside the constructor.
- constructor(
- private formBuilder : FormBuilder,
- private router : Router,
- private authService : AuthService
- ) { }
Create a new variable modal as ILogin interface and set default parameters.
- model: ILogin = { userid: "admnin", password: "admin@123" }
Create loginForm variable as type FormGroup. Message as type string and returnURL as type of string.
- loginForm: FormGroup;
- message: string;
- returnUrl: string;
Inside ngOnInit() metod, create new formGroup and add required validation on both properties.
- ngOnInit() {
- this.loginForm = this.formBuilder.group({
- userid: ['', Validators.required],
- password: ['', Validators.required]
- });
- this.returnUrl = '/dashboard';
- this.authService.logout();
- }
Add get method for easy form access.
- // convenience getter for easy access to form fields
- get f() { return this.loginForm.controls; }
Add Login() method inside this class.
- login() {
- // stop here if form is invalid
- if (this.loginForm.invalid) {
- return;
- }
- else {
- if (this.f.userid.value == this.model.userid && this.f.password.value == this.model.password) {
- console.log("Login successful");
- //this.authService.authLogin(this.model);
- localStorage.setItem('isLoggedIn', "true");
- localStorage.setItem('token', this.f.userid.value);
- this.router.navigate([this.returnUrl]);
- }
- else {
- this.message = "Please check your userid and password";
- }
- }
- }
So, login.component.ts will look like this,
- import { Component, OnInit } from '@angular/core';
- import { Router } from '@angular/router';
- import { ILogin } from 'src/app/interfaces/login';
- import { AuthService } from '../services/auth.service'
- import { FormBuilder, FormGroup, Validators } from '@angular/forms';
- @Component({
- selector: 'app-login',
- templateUrl: './login.component.html',
- styleUrls: ['./login.component.css']
- })
- export class LoginComponent implements OnInit {
- model: ILogin = { userid: "admnin", password: "admin@123" }
- loginForm: FormGroup;
- message: string;
- returnUrl: string;
- constructor(
- private formBuilder: FormBuilder,
- private router: Router,
- private authService: AuthService
- ) { }
- ngOnInit() {
- this.loginForm = this.formBuilder.group({
- userid: ['', Validators.required],
- password: ['', Validators.required]
- });
- this.returnUrl = '/dashboard';
- this.authService.logout();
- }
- // convenience getter for easy access to form fields
- get f() { return this.loginForm.controls; }
- login() {
- // stop here if form is invalid
- if (this.loginForm.invalid) {
- return;
- }
- else {
- if (this.f.userid.value == this.model.userid && this.f.password.value == this.model.password) {
- console.log("Login successful");
- //this.authService.authLogin(this.model);
- localStorage.setItem('isLoggedIn', "true");
- localStorage.setItem('token', this.f.userid.value);
- this.router.navigate([this.returnUrl]);
- }
- else {
- this.message = "Please check your userid and password";
- }
- }
- }
- }
Login.component.html
- <div class="container">
- <div class="col-md-6 col-md-offset-3 loginBox">
- <h3>Log In</h3>
- <p *ngIf="message" class="text-center error">{{message}}</p>
- <form [formGroup]="loginForm" (ngSubmit)="login()">
- <div class="form-group clearfix" [ngClass]="{ 'has-error': submitted && f.userid.errors }">
- <label for="userid" class="col-md-3 col-sm-5 col-xs-12">Userid</label>
- <div class="col-md-9 col-sm-7 col-xs-12">
- <input type="text" class="form-control" formControlName="userid" />
- <div *ngIf="submitted && f.userid.errors" class="help-block">
- <div *ngIf="f.userid.errors.required">Userid is required</div>
- </div>
- </div>
- </div>
- <div class="form-group clearfix" [ngClass]="{ 'has-error': submitted && f.password.errors }">
- <label for="password" class="col-md-3 col-sm-5 col-xs-12">Password</label>
- <div class="col-md-9 col-sm-7 col-xs-12">
- <input type="password" class="form-control" formControlName="password"/>
- <div *ngIf="submitted && f.password.errors" class="help-block">
- <div *ngIf="f.password.errors.required">Password is required</div>
- </div>
- </div>
- </div>
- <div class="col-xs-12 form-group text-right">
- <button class="btn btn-success" type="submit">Login</button>
- </div>
- </form>
- </div>
- </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.
- import { Component, OnInit } from '@angular/core';
- import { Router } from '@angular/router';
- import { AuthService } from '../services/auth.service';
- @Component({
- selector: 'app-dashboard',
- templateUrl: './dashboard.component.html',
- styleUrls: ['./dashboard.component.css']
- })
- export class DashboardComponent implements OnInit {
- id: string;
- constructor(private router: Router, private authService: AuthService) { }
- ngOnInit() {
- this.id = localStorage.getItem('token');
- //console.log(this.id);
- }
- logout() {
- console.log('logout');
- this.authService.logout();
- this.router.navigate(['/login']);
- }
- }
Dashboard.component.html
This page will display if the user is authorized and display the logged user's id inside {{id}}.
- <div class="container">
- <div class="col-md-6 col-md-offset-3 loginBox">
- Welcome, {{id}}
- <a href="javascript:void(0);" (click)="logout()">Logout</a>
- </div>
- </div>
No comments:
Post a Comment