刷新令牌拦截器离子时捕获错误

问题描述 投票:0回答:1

我正在使用离子3,角度5和rxjs 5.我在我的应用程序中制作截取器,并且可以很好地拦截所有传出的API,并在原始令牌过期时向标头添加令牌并刷新令牌。

import {Observable, BehaviorSubject} from 'rxjs';
import {_throw} from "rxjs/observable/throw";

import {take, filter, catchError, switchMap, finalize} from 'rxjs/operators';
import {Injectable, Injector} from "@angular/core";
import {HttpInterceptor, HttpRequest, HttpHandler, HttpSentEvent, HttpHeaderResponse, HttpProgressEvent,
  HttpResponse, HttpUserEvent, HttpErrorResponse} from "@angular/common/http";

import {ResetApiProvider} from "../providers/reset-api/reset-api";
import {Events} from "ionic-angular";

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  isRefreshingToken: boolean = false;
  tokenSubject: BehaviorSubject<string> = new BehaviorSubject<string>(null);

  constructor(private injector: Injector, public event: Events) {}

  addToken(req: HttpRequest<any>, token: string): HttpRequest<any> {
    return req.clone({setHeaders: {Authorization: 'Bearer ' + token}})
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
    const authService = this.injector.get(ResetApiProvider);

    return next.handle(this.addToken(req, authService.getAuthToken())).pipe(
      catchError(error => {
        if (error instanceof HttpErrorResponse) {
          switch ((<HttpErrorResponse>error).status) {
            case 400:
              return this.handle400Error(error);
            case 401:
              return this.handle401Error(req, next);
            default:
              return _throw(error);
          }
        } else {
          return _throw(error);
        }
      }));
  }

  //maybe use later for blacklist tokens
  handle400Error(error) {
    if (error && error.status === 400 && error.error && error.error.error === 'invalid_grant') {
      // If we get a 400 and the error message is 'invalid_grant', the token is no longer valid so logout.
      return this.logoutUser();
    }

    return _throw(error);
  }

  handle401Error(req: HttpRequest<any>, next: HttpHandler) {
    if (!this.isRefreshingToken) {
      this.isRefreshingToken = true;

      // Reset here so that the following requests wait until the token
      // comes back from the refreshToken call.
      this.tokenSubject.next(null);

      const authService = this.injector.get(ResetApiProvider);

      return authService.refreshToken().pipe(
        switchMap((newToken: string) => {
          console.log('bbbbbbb');
          if (newToken) {
            this.tokenSubject.next(newToken);
            return next.handle(this.addToken(req, newToken));
          }
          console.log('qqqq');

          // If we don't get a new token, we are in trouble so logout.
          return this.logoutUser();
        }),
        catchError(error => {
          // If there is an exception calling 'refreshToken', bad news so logout.
          return this.logoutUser();
        }),
        finalize(() => {
          this.isRefreshingToken = false;
        }),);
    } else {
      return this.tokenSubject.pipe(
        filter(token => token != null),
        take(1),
        switchMap(token => {
          return next.handle(this.addToken(req, token));
        }),);
    }
  }

  logoutUser() {
    const authService = this.injector.get(ResetApiProvider);
    authService.logout();
    this.event.publish('UNAUTHORIZED');
    return _throw("please login");
  }


}

我的刷新令牌功能:

public refreshToken(): Observable<string> {
    const url = `${apiUrl}/auth/refresh`;
    console.log('fffff');
    return this.http.post(url, {token: this.getAuthToken()},httpOptions)
      .pipe(
        map((res) => {
          let token: any = res;
          this.storage.set('token', token.data);
          console.log(token.data);
          this.currentToken = token.data;
           return  token.data;
        catchError(this.handleError)
      );
  }

除了,如果refreshToken()失败,catch()和finally()永远不会到达AuthInterceptor类!!如何解决这个问题!?所以我无法清除存储并导航到登录页面。

javascript angular rxjs ionic3 interceptor
1个回答
1
投票

尝试这个调整。

public refreshToken(): Observable<string> {
    const url = `${apiUrl}/auth/refresh`;
    console.log('fffff');
    return this.http.post(url, {token: this.getAuthToken()},httpOptions)
      .pipe(
        map((res) => {
          let token: any = res;
          this.storage.set('token', token.data);
          console.log(token.data);
          this.currentToken = token.data;
          //return  token.data;
        }),
        catchError(this.handleError)
      );
}
  • 即return和catchError之间缺少的}),
  • 返回似乎也是多余的,所以我评论说。

对于here

如果有帮助,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.