DEV Community

Cover image for Login and signup example in Angular
eavnitech
eavnitech

Posted on • Updated on • Originally published at eavnitech.com

Login and signup example in Angular

Angular is the most trending js frameworks for the single page App and front end development, now i am here to explain how the login/authentication functionality works in angular.
Here are some basic concepts of authentication:

How the authentication works

In angular if a use enters the email and password on the login page then the email/password should be validated from the backend server, so we should call a login API and the API will validate the passed email/password. so for calling the server we use the HTTP library

a. How to call the backend API

Here in the code, we created a login function and we are passing login form data(email and password).
this function sends a request to the server and receives the response from the server.

  login(formData:any):Observable<HttpResponse<CommonResponse>>{
    return this.http.post<CommonResponse>(this.endPoint+"login", formData,  { observe: 'response' })
    .pipe(
      tap((resp: HttpResponse<CommonResponse>) => {
        if(resp.headers.get('x-auth')){
          this.cookieService.set("currentUser",resp.headers.get('x-auth'));
          this.loginStatus.next(true);
        }
        return resp;  
      }),
      catchError(this.handleError)
    );
  }
Enter fullscreen mode Exit fullscreen mode

b. How to manage the authentication

So to manage the authentication, angular provides the route guards, by using the guard we can restrict the end-user to open the page which one we don't want to open the page without login.
After getting the response from the server, we store the token in the cookie

  if(resp.headers.get('x-auth')){
    this.cookieService.set("currentUser",resp.headers.get('x-auth'));
    this.loginStatus.next(true);
  }
Enter fullscreen mode Exit fullscreen mode

Here in this code, we are checking the cookie is there or not, if there is a cookie what we have put in the login function then the user is logged in.

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

    if (this.cookieService.get('currentUser')) {
        // logged in so return true
        return true;
    }

    // not logged in so redirect to login page with the return url
    this.router.navigate(['/login']);
    return false;
  }
Enter fullscreen mode Exit fullscreen mode

Installation:

Install the Angular CLI

npm install -g @angular/cli

Create a workspace and initial application

ng new login-in-angular

cd new login-in-angular

npm start

Lets build a login application

install the cookie package
npm i ngx-cookie-service

1. Create the login component

//File location in login folder and file name login.component.ts
  import { Component, OnInit } from '@angular/core';
  import {FormGroup, FormControl, Validators} from '@angular/forms';
  import { Router } from '@angular/router';
  import { CommonResponse } from "../common/common-response";
  import { ApiService } from "../auth/api.service";
  @Component({
    selector: 'app-login',
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.css']
  })
  export class LoginComponent implements OnInit {

    loginForm = new FormGroup({
      email: new FormControl('', [Validators.required, Validators.email]),
      password: new FormControl('', [Validators.required])
    })

    public loginError:String;
    constructor(private apiService:ApiService,private router: Router) { }

    ngOnInit() {
    }

    onSubmit(){  
      if(this.loginForm.valid){
        this.apiService.login(this.loginForm.value)
        .subscribe((data) => { console.log(data);
          if(data.status === 200 && !data.body.ErrorCode){
            this.router.navigate(['/dashboard']);
          }else{
            this.loginError = data.body.message;
          }        
        },
        error => this.loginError = error
        )
      }    
    }
  }
Enter fullscreen mode Exit fullscreen mode
<!-- File location in login folder and file name login.component.html -->
  <div class="form-signin">
    <form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
      <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
      <p *ngIf="loginError">{{loginError}}</p>
      <mat-form-field>
        <input matInput placeholder="Enter your email" formControlName="email" required>
        <mat-error *ngIf="!loginForm.controls.email.valid">Please enter valid email id</mat-error>
      </mat-form-field>
      <mat-form-field>
         <input matInput placeholder="Enter your password" type="password" formControlName="password" required>
         <mat-error *ngIf="!loginForm.controls.password.valid">Please enter password</mat-error>
      </mat-form-field><br/>
      <button type="submit" mat-raised-button color="warn">Login</button>
    </form>
  </div>
Enter fullscreen mode Exit fullscreen mode

2. Create the auth service

  // folder name auth and file name api.service.ts
  import { Injectable } from '@angular/core';
  import { HttpClient, HttpResponse, HttpErrorResponse } from '@angular/common/http';
  import { CookieService } from 'ngx-cookie-service';
  import { Observable, throwError, BehaviorSubject } from 'rxjs';
  import { catchError, map, tap } from 'rxjs/operators';
  import { Router } from '@angular/router';

  import { CommonResponse } from "../common/common-response";
  @Injectable({
    providedIn: 'root'
  })
  export class ApiService {
    private endPoint:string = "/api/";
    loginStatus = new BehaviorSubject<boolean>(this.hasToken());


    constructor(private http: HttpClient, private cookieService: CookieService, private router: Router ) {}
    /**
     * 
     * @param formData as the login form data
     */
    login(formData:any):Observable<HttpResponse<CommonResponse>>{
      return this.http.post<CommonResponse>(this.endPoint+"login",formData,  { observe: 'response' })
      .pipe(
        tap((resp: HttpResponse<CommonResponse>) => {
          if(resp.headers.get('x-auth')){
            this.cookieService.set("currentUser",resp.headers.get('x-auth'));
            this.loginStatus.next(true);
          }
          return resp;  
        }),
        catchError(this.handleError)
      );
    }
    /**
     * 
     * @param error error 
     */
    private handleError(error: HttpErrorResponse) {
      if (error.error instanceof ErrorEvent) {
        // A client-side or network error occurred. Handle it accordingly.
        console.error('An error occurred:', error.error.message);
      } else {
        // The backend returned an unsuccessful response code.
        // The response body may contain clues as to what went wrong,
        console.error(
          `Backend returned code ${error.status}, ` +
          `body was: ${error.error}`);
      }
      // return an observable with a user-facing error message
      return throwError(
        'Something bad happened; please try again later.');
    };

    logout(){
      this.loginStatus.next(false);

      this.cookieService.deleteAll();
      this.router.navigate(['/login']);
    }

  /**
  *
  * @returns {Observable<T>}
  */
   isLoggedIn() : Observable<boolean> {
    return this.loginStatus.asObservable();
   }
   /**
   * if we have token the user is loggedIn
   * @returns {boolean}
   */
   private hasToken() : boolean {
     return this.cookieService.check('currentUser');
   }
  }
Enter fullscreen mode Exit fullscreen mode

3. Create the auth guard

 // Folder name auth and file name auth.guard.ts
 import { Injectable } from '@angular/core';
 import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
 import { Observable } from 'rxjs';
 import { CookieService } from 'ngx-cookie-service';

 @Injectable({
   providedIn: 'root'
 })
 export class AuthGuard implements CanActivate {
   constructor(private cookieService: CookieService, private router: Router) { }

   canActivate(
     next: ActivatedRouteSnapshot,
     state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

     if (this.cookieService.get('currentUser')) {
        // logged in so return true
        return true;
     }

     // not logged in so redirect to login page with the return url
     this.router.navigate(['/login']);
     return false;
   }
 }
Enter fullscreen mode Exit fullscreen mode

Demo

You can check the demo from Here and can get the code from the Github repo

Top comments (0)