Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在JWT令牌在7中过期时显示警报或烤面包机消息_Javascript_Angular_Angular7_Angular Http Interceptors - Fatal编程技术网

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

Javascript 如何在JWT令牌在7中过期时显示警报或烤面包机消息,javascript,angular,angular7,angular-http-interceptors,Javascript,Angular,Angular7,Angular Http Interceptors,当JWT令牌过期时,web应用程序应该显示一个警报或模式弹出窗口,然后它应该重定向到登录页面。目前我正在使用烤面包机信息 我的组件中有很多api调用。我收到许多“token expired”的烤面包机消息。我应该只显示一条消息并重定向到登录页面。告诉我你的好主意。我在网上有一些文章。但是我不能把这些事情弄清楚 import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpRespons

当JWT令牌过期时,web应用程序应该显示一个
警报或模式弹出窗口,然后它应该重定向到登录页面。目前我正在使用烤面包机信息

我的组件中有很多api调用。我收到许多“token expired”的烤面包机消息。我应该只显示一条消息并重定向到登录页面。告诉我你的好主意。我在网上有一些文章。但是我不能把这些事情弄清楚

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);
          })
        );
    }
   }
导入{
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpResponse,
HttpErrorResponse
}来自“@angular/common/http”;
从“rxjs”导入{observatable,throwerr};
从“rxjs/operators”导入{retry,catchError};
从'@angular/Router'导入{Router};
从“ng6 toastr通知”导入{ToastrManager};
从“@angular/core”导入{Injectable};
从“./jwt decoder.service”导入{JwtDecoderService};
@可注射()
导出类HttpErrorInterceptor实现HttpInterceptor{
构造函数(公共路由器:路由器、,
公共收件人:ToastrManager,
专用jwtDecoder:JwtDecoderService,){
}
拦截(请求:HttpRequest,下一步:HttpHandler):可观察{
if(localStorage.getItem('isLoggedin')=='false'&&!this.jwtDecoder.isTokenExpired()){
此.toastr.warningToastr('Token expired');
返回;
}
返回next.handle(请求)
.烟斗(
catchError((错误:HttpErrorResponse)=>{
让errorMessage='';
if(error.error instanceof ErrorEvent){
//客户端错误
errorMessage=`Error:${Error.Error.message}`;
}否则{
//服务器端错误
errorMessage=`错误代码:${Error.status}\n消息:${Error.message}`;
如果(error.status==404){
this.toastr.warningToastr('Server Not Found');
this.router.navigate(['/login']);
}
如果(error.status==412){
此.toastr.warningToastr('Token expired');
this.router.navigate(['/login']);
}
//如果(error.status==500 | | error.status==400){
//this.toastr.errorToastr('我们遇到了一个技术问题');
// }
}
//返回投掷器(错误消息);
返回投掷器(错误);
})
);
}
}

您可以使用HttpInterceptor。因为每个API调用都通过拦截器,所以您可以检查令牌是否仍然有效,继续API调用

如果令牌过期,则显示toastr警报并阻止任何进一步的API调用

有关使用拦截器的更多信息,请访问此

完整代码:

http拦截器.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 => {
          })
        )
    }

  }
}
 providers: [
    {
        provide: HTTP_INTERCEPTORS,
        useClass: HttpInterceptorService,
        multi: true
      }
   ]
  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');

  }
会话服务.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 => {
          })
        )
    }

  }
}
 providers: [
    {
        provide: HTTP_INTERCEPTORS,
        useClass: HttpInterceptorService,
        multi: true
      }
   ]
  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');

  }

为什么不使用
路由器。在第一个分支中导航
,而不仅仅是
返回
?更干净的方法是在特定的服务中考虑这种行为,这样你总是调用相同的行为,而不是在多个分支中重复它。因为你的所有API都使用JWT令牌进行身份验证,所以最好先检查令牌的有效性,然后再进行其他API调用。我有疑问。APICALL是否只通过拦截器?或者我从云中得到了很多库和图像。我是说从互联网上。图像和库(如boostrap、jquery)是否只通过侦听器API调用。您可以通过拦截器设置身份验证令牌、显示加载程序等。如果添加拦截器,所有API调用都将通过it@GeorgKastenhofer