This tutorial is another step for beginner implementing the login logout functionality in angular 8.
Mainly to focus on
- How to make an API call from the angular application?
- How to Maintain user session in the whole application?
- How to authenticate users through route guard?
Required steps to achieve the functionality:
First, we create a user details table in MySQL table, which contains the field of email, password, mobile no, then establishes the PHP Pages for handling the Http Request Get, Post, Put method. In short, create login.php, registration.php, and config.php.
Script for table
CREATE TABLE `employee` ( `Id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL, `pwd` varchar(100) NOT NULL, `email` varchar(60) DEFAULT NULL, `mobile` varchar(100) NOT NULL, PRIMARY KEY (`Id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
config.php
<?php header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: PUT, GET, POST, DELETE"); header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept"); $db_username = 'root'; $db_password = 'airtel'; $db_name = 'ng'; $db_host = 'localhost'; $mysqli = new mysqli($db_host, $db_username, $db_password,$db_name); if ($mysqli->connect_error) { die('Error : ('. $mysqli->connect_errno .') '. $mysqli->connect_error); } ?>
login.php
<?php include_once("config.php"); $postdata = file_get_contents("php://input"); $request = json_decode($postdata); if(isset($postdata) && !empty($postdata)) { $pwd = mysqli_real_escape_string($mysqli, trim($request->password)); $email = mysqli_real_escape_string($mysqli, trim($request->username)); $sql=''; $sql = "SELECT * FROM employee where email='$email' and pwd='$pwd'"; if($result = mysqli_query($mysqli,$sql)) { $rows = array(); while($row = mysqli_fetch_assoc($result)) { $rows[] = $row; } echo json_encode($rows); } else { http_response_code(404); } } ?>
registration.php
<?php include_once("config.php"); $postdata = file_get_contents("php://input"); $request = json_decode($postdata); if(isset($postdata) && !empty($postdata)) { $name = mysqli_real_escape_string($mysqli, trim($request->name)); $pwd = mysqli_real_escape_string($mysqli, (int)$request->pwd); $email = mysqli_real_escape_string($mysqli, trim($request->email)); $mobile = mysqli_real_escape_string($mysqli, (int)$request->mobile); $sql = "INSERT INTO employee(name,pwd,email,mobile) VALUES ('{$name}','{$pwd}','{$email}','{$mobile}')"; // echo $sql; if ($mysqli->query($sql) === TRUE) { $authdata = [ 'name' => $name, 'pwd' => '', 'email' => $email, 'mobile' => $mobile, 'Id' => mysqli_insert_id($mysqli) ]; echo json_encode($authdata); } } ?>
Now let’s ready to work on angular. Create modules that represent the data, Components for Html layout and javascript functionality, Service file for common feature, or sharing data between the components.
The flow of functionality:
Getting the user input from the registration component and passing the data to the database through API for creating a user account, then getting the value of username and password from the login page and authenticate the user through API. If the user is authenticated, storing the data in local storage, which we can use globally. For example, if the user is logging in, then showing the logout button, username, and hiding the login button.
login.component.html
<h2 class="text-center">Login</h2> <div class="row"> <div class="col-md-3"> </div> <div class="col-md-6 col-md-offset-3"> <div class="jumbotron"> <form [formGroup]="angForm" (ngSubmit)="postdata(angForm)" autocomplete="off" > <div class="form-group"> <label for="email">User Name</label> <input type="email" name="email" formControlName="email" autocomplete="off" class="form-control input-sm" placeholder="Email Address"> </div> <div class="form-group"> <label for="Password">Password</label> <input type="password" name="Password" formControlName="password" autocomplete="off" class="form-control input-sm" placeholder="Password"> </div> <button type="submit" class="btn btn-primary" [disabled]="!angForm.valid">Login</button> </form> </div> </div> <div class="col-md-3"> </div> </div>
login.component.ts
import { Component, OnInit } from '@angular/core'; import { FormGroup, FormBuilder, Validators, NgForm } from '@angular/forms'; import { first } from 'rxjs/operators'; import { Router } from '@angular/router'; import { DataserviceService } from '../dataservice.service'; @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.css'] }) export class LoginComponent implements OnInit { angForm: FormGroup; constructor(private fb: FormBuilder,private dataService: DataserviceService,private router:Router) { this.angForm = this.fb.group({ email: ['', [Validators.required,Validators.minLength(1), Validators.email]], password: ['', Validators.required] }); } ngOnInit() { } postdata(angForm1:NgForm) { this.dataService.userlogin(angForm1.value.email,angForm1.value.password) .pipe(first()) .subscribe( data => { const redirect = this.dataService.redirectUrl ? this.dataService.redirectUrl : '/dashboard'; this.router.navigate([redirect]); }, error => { alert("User name or password is incorrect") }); } get email() { return this.angForm.get('email'); } get password() { return this.angForm.get('password'); } }
registration.component.html
<h2 class="text-center">Registration</h2> <div class="row"> <div class="col-md-3"> </div> <div class="col-md-6 col-md-offset-3"> <div class="jumbotron"> <form [formGroup]="angForm" (ngSubmit)="postdata(angForm)" autocomplete="off" > <div class="form-group"> <label for="name">User Name</label> <input type="text" name="name" formControlName="name" autocomplete="off" class="form-control input-sm" placeholder="User Name"> </div> <div class="form-group"> <label for="email">Email</label> <input type="email" name="email" formControlName="email" autocomplete="off" class="form-control input-sm" placeholder="Email Address"> </div> <div class="form-group"> <label for="Password">Password</label> <input type="password" name="Password" formControlName="password" autocomplete="off" class="form-control input-sm" placeholder="Password"> </div> <div class="form-group"> <label for="name">Mobile No</label> <input type="text" name="mobile" formControlName="mobile" autocomplete="off" class="form-control input-sm" placeholder="Mobile No"> </div> <button type="submit" class="btn btn-primary" [disabled]="!angForm.valid">Registration</button> </form> </div> </div> <div class="col-md-3"> </div> </div>
registration.component.ts
import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, FormBuilder, Validators, NgForm } from '@angular/forms'; import { first } from 'rxjs/operators'; import { Router } from '@angular/router'; import { DataserviceService } from '../dataservice.service'; @Component({ selector: 'app-registration', templateUrl: './registration.component.html', styleUrls: ['./registration.component.css'] }) export class RegistrationComponent implements OnInit { angForm: FormGroup; constructor(private fb: FormBuilder,private dataService: DataserviceService,private router:Router) { this.angForm = this.fb.group({ email: ['', [Validators.required,Validators.minLength(1), Validators.email]], password: ['', Validators.required], name: ['', Validators.required], mobile: ['', Validators.required] }); } ngOnInit() { } postdata(angForm1:NgForm) { this.dataService.userregistration(angForm1.value.name,angForm1.value.email,angForm1.value.password,angForm1.value.mobile) .pipe(first()) .subscribe( data => { this.router.navigate(['login']); }, error => { }); } get email() { return this.angForm.get('email'); } get password() { return this.angForm.get('password'); } get name() { return this.angForm.get('name'); } get mobile() { return this.angForm.get('mobile'); } }
app.component.html
<nav class="navbar navbar-expand-lg navbar-light bg-light rounded"> <a class="navbar-brand" routerLink="home" routerLinkActive="active">M Tutorial</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExample09" aria-controls="navbarsExample09" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarsExample09"> <ul class="navbar-nav mr-auto"> <li class="nav-item"> <a class="nav-link" *ngIf="loginbtn" routerLink="login" routerLinkActive="active">Login</a> </li> <li class="nav-item"> <button type="button" *ngIf="logoutbtn" class="btn btn-danger btn-block" (click)="logout()">logout</button> </li> <li class="nav-item"> <a class="nav-link" *ngIf="loginbtn" routerLink="registration" routerLinkActive="active">Registration</a> </li> <li class="nav-item"> <a class="nav-link" *ngIf="logoutbtn" routerLink="dashboard" routerLinkActive="active">Dashboard</a> </li> </ul> </div> </nav> <router-outlet></router-outlet>
app.component.ts
import { Component } from '@angular/core'; import { DataserviceService } from './dataservice.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { loginbtn:boolean; logoutbtn:boolean; constructor(private dataService: DataserviceService) { dataService.getLoggedInName.subscribe(name => this.changeName(name)); if(this.dataService.isLoggedIn()) { console.log("loggedin"); this.loginbtn=false; this.logoutbtn=true } else{ this.loginbtn=true; this.logoutbtn=false } } private changeName(name: boolean): void { this.logoutbtn = name; this.loginbtn = !name; } logout() { this.dataService.deleteToken(); window.location.href = window.location.href; } }
app-routing.module.ts
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { LoginComponent } from './login/login.component'; import { RegistrationComponent } from './registration/registration.component'; import { DashboardComponent } from './dashboard/dashboard.component'; import { AuthguardGuard } from './authguard.guard'; const routes: Routes = [ { path: '', component: LoginComponent }, { path: 'login', component: LoginComponent }, { path: 'registration', component: RegistrationComponent }, { path: 'dashboard', component: DashboardComponent,canActivate: [AuthguardGuard] } ] @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import {FormsModule,ReactiveFormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { LoginComponent } from './login/login.component'; import { RegistrationComponent } from './registration/registration.component'; import { DashboardComponent } from './dashboard/dashboard.component'; @NgModule({ declarations: [ AppComponent, LoginComponent, RegistrationComponent, DashboardComponent ], imports: [ BrowserModule, AppRoutingModule, FormsModule, HttpClientModule, ReactiveFormsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
usermodule.ts
export class Usermodule { public Id: number; public name: string; public pwd:string; public email:string; public mobile:string; constructor(Id:number,name: string,pwd:string,email:string,mobile:string) { this.Id = Id; this.name = name; this.pwd = pwd; this.email = email; this.mobile=mobile; } }
dataservice.service.ts
import { Injectable, Output, EventEmitter } from '@angular/core'; import { map } from 'rxjs/operators'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class DataserviceService { redirectUrl: string; baseUrl:string = "http://localhost/uat/api"; @Output() getLoggedInName: EventEmitter<any> = new EventEmitter(); constructor(private httpClient : HttpClient) { } public userlogin(username, password) { return this.httpClient.post<any>(this.baseUrl + '/login.php', { username, password }) .pipe(map(Usermodule => { this.setToken(Usermodule[0].name); this.getLoggedInName.emit(true); return Usermodule; })); } public userregistration(name,email,pwd,mobile) { return this.httpClient.post<any>(this.baseUrl + '/registration.php', { name,email, pwd,mobile }) .pipe(map(Usermodule => { return Usermodule; })); } //token setToken(token: string) { localStorage.setItem('token', token); } getToken() { return localStorage.getItem('token'); } deleteToken() { localStorage.removeItem('token'); } isLoggedIn() { const usertoken = this.getToken(); if (usertoken != null) { return true } return false; } }
authguard.guard.ts
import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, CanActivate, Router } from '@angular/router'; import { DataserviceService } from './dataservice.service'; @Injectable({ providedIn: 'root' }) export class AuthguardGuard implements CanActivate { constructor(private dataService: DataserviceService,private router: Router ) {} canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { const routeurl: string = state.url; return this.isLogin(routeurl); } isLogin(routeurl: string) { if (this.dataService.isLoggedIn()) { return true; } this.dataService.redirectUrl = routeurl; this.router.navigate(['/login'], {queryParams: { returnUrl: routeurl }} ); } }
Technical scenario and their solution for crud application:
Restricts anonymous user to access the “dashboard” component through the "Auth guard" “canactivate” in-built function.
Followed the http and https verbs (POST, GET, Delete) to achieve the Restful API principles.
All the API functions are implementing in “dataservice.service.ts” file with “RxJs” http calls.
Continue our angular 8 crud example in our next tutorial. So that you can understand insert, delete, update, read using php API.
User session maintained through local storage variables to identify the user logged in or not.
No comments:
Post a Comment