简体   繁体   English

当 JWT 令牌在 Angular 7 中过期时如何显示警报或烤面包机消息

[英]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.当 JWT 令牌过期时,Web 应用程序应显示alert或模式弹出窗口,然后应重定向到登录页面。 Currently I am using toaster message.目前我正在使用烤面包机消息。

I have many api calls in my component.我的组件中有很多 api 调用。 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 .您可以使用HttpInterceptor Since every API call passes trough interceptor, you can check if the token is still valid, proceed with the API call由于每个 API 调用都通过拦截器,您可以检查令牌是否仍然有效,继续 API 调用

If the token expired, show toastr alert and prevent any further API call.如果令牌过期,则显示 toastr 警报并阻止任何进一步的 API 调用。

For more info on using interceptor, visit this 10 ways to use Interceptors and Angular 7 JWT Interceptor有关使用拦截器的更多信息,请访问使用拦截器Angular 7 JWT 拦截器的10 种方法

Complete Code:完整代码:

http-interceptor.service.ts 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 app.module.ts

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

session-service.ts会话服务.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');

  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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