简体   繁体   中英

How to show an alert or toaster message when the JWT token expires in Angular 7

When a JWT token expires, the web app should show an alert or modal pop up, then it should redirect to login page. Currently I am using toaster message.

I have many api calls in my component. I get many toaster messages 'token expired'. I should show a message only and redirect to login page. tell me your good idea. I have some articles in the internet. But I could not get those things clearly.

import {
    HttpEvent,
    HttpInterceptor,
    HttpHandler,
    HttpRequest,
    HttpResponse,
    HttpErrorResponse
   } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';
import { Router } from '@angular/router';
import { ToastrManager } from 'ng6-toastr-notifications';
import { Injectable } from '@angular/core';
import { JwtDecoderService } from './jwt-decoder.service';

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {

    constructor(public router: Router,
                public toastr: ToastrManager,
                private jwtDecoder: JwtDecoderService, ) {
    }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
      if (localStorage.getItem('isLoggedin') === 'false' && !this.jwtDecoder.isTokenExpired()) {
        this.toastr.warningToastr('Token expired');
        return;
      }
      return next.handle(request)
        .pipe(
          catchError((error: HttpErrorResponse) => {
            let errorMessage = '';
            if (error.error instanceof ErrorEvent) {
              // client-side error
              errorMessage = `Error: ${error.error.message}`;
            } else {
              // server-side error
              errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
              if (error.status === 404) {
                this.toastr.warningToastr('Server Not Found');
                this.router.navigate(['/login']);
              }
              if (error.status === 412) {
                this.toastr.warningToastr('Token expired');
                this.router.navigate(['/login']);
              }
              // if (error.status === 500 || error.status === 400) {
              //   this.toastr.errorToastr('We encountered a technical issue');
              // }
            }
            // return throwError(errorMessage);
            return throwError(error);
          })
        );
    }
   }

You can use HttpInterceptor . Since every API call passes trough interceptor, you can check if the token is still valid, proceed with the API call

If the token expired, show toastr alert and prevent any further API call.

For more info on using interceptor, visit this 10 ways to use Interceptors and Angular 7 JWT Interceptor

Complete Code:

http-interceptor.service.ts

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { SessionService } from './session.service';
import { Router } from '@angular/router';
import { throwError } from 'rxjs';

declare var toastr;

@Injectable({
  providedIn: 'root'
})
export class HttpInterceptorService implements HttpInterceptor {

  constructor(private router: Router, private sessionService: SessionService) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    var token = this.sessionService.getToken();
    if (token != null && this.sessionService.isTokenExpired()) {
      this.sessionService.logOut()
      toastr.warning("Session Timed Out! Please Login");
      this.router.navigate(['/login'])
      return throwError("Session Timed Out")
    } else {

      const authRquest = req.clone({
        setHeaders: {
          Authorization: 'Bearer ' + token
        }
      })
      return next.handle(authRquest)
        .pipe(
          tap(event => {
          }, error => {
          })
        )
    }

  }
}

app.module.ts

 providers: [
    {
        provide: HTTP_INTERCEPTORS,
        useClass: HttpInterceptorService,
        multi: true
      }
   ]

session-service.ts

  getToken(): string {
    return localStorage.getItem('userToken');
  }

  getTokenExpirationDate(token: string): Date {
    token = this.getToken()
    const decoded = jwt_decode(token);

    if (decoded.exp === undefined) return null;

    const date = new Date(0);
    date.setUTCSeconds(decoded.exp);
    return date;
  }

  isTokenExpired(token?: string): boolean {
    if (!token) token = this.getToken();
    if (!token) return true;

    const date = this.getTokenExpirationDate(token);
    if (date === undefined) return false;
    return !(date.valueOf() > new Date().valueOf());
  }

  logOut(loginType?: string) {
    localStorage.removeItem('isLoggedin');
    localStorage.removeItem('userRole');

  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM