401没有参加刷新令牌故障事件



auth Service未在刷新令牌401上记录。取而代之的是catherror.ts。该应用程序如何处理此操作。

场景1.最初使用基本授权标头获取访问令牌。2.用访问令牌进行服务器调用。3.访问TOEKN过期后,致电刷新令牌服务。4.在刷新代币中的呼叫是成功的,请使用新的代币进行其余的服务呼叫。5.在"刷新" toeken失败上,将返回401错误,但是该应用程序无法捕获错误,并且永远不会记录。

使用Angular 4 HTTP Interceptor

这是拦截器

import { Injectable, Injector } from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse, HttpErrorResponse, HttpClient} from '@angular/common/http';
import * as AppUtils from '../common/app.utils';
import { AuthService } from './auth.service';
import {Observable} from 'rxjs/Rx';
import { 
    Router,
    Event, 
    NavigationStart, RoutesRecognized, NavigationEnd, NavigationCancel, NavigationError
} from '@angular/router'
import { LoaderService } from '../loader/loader.service'
import { BehaviorSubject } from "rxjs/BehaviorSubject";
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
import { EmptyObservable } from 'rxjs/observable/EmptyObservable';
import { catchError, filter, take, switchMap, finalize } from "rxjs/operators";
import { SharedService } from '../common/services/shared.service';
declare var swal: any;
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
 isRefreshingToken: boolean = true;
 tokenSubject: BehaviorSubject<string> = new BehaviorSubject<string>(null);
 constructor(private inj: Injector, private router: Router) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
     const auth = this.inj.get(AuthService)  
       return next.handle(this.addToken(request))
      .pipe(
      catchError((error, ca) => {
        if (error instanceof HttpErrorResponse) {
          switch ((<HttpErrorResponse>error).status) {
            case 401:
              return this.handle401Error(request, next, auth)
            default:
              return ErrorObservable.create(error);
          }
        } else {
          return ErrorObservable.create(error);
        }
      })
      )
  }
addToken(req: HttpRequest<any>): HttpRequest<any> {
    let customReq: any;
    let client_id = 'test'; 
    let client_secret= 'secret';
    let basicheader = btoa(client_id +':'+ client_secret);
    if(req.url.indexOf("token?grant_type") < 0 || req.url.indexOf("token?grant_type") == 0){
            customReq = req.clone({
                headers: req.headers.set('Content-Type', 'application/json')
                                    .set('Authorization','Bearer '+ localStorage.getItem(AppUtils.STORAGE_ACCOUNT_ACCESS_TOKEN))
            })
                //Set estCode and perscode for Alshif Users
                if(localStorage.getItem(AppUtils.ALSHIFA_TRUSTED_LOGIN)!=null && localStorage.getItem(AppUtils.ALSHIFA_TRUSTED_LOGIN)==="Y"){
                    req.headers.append(AppUtils.ALSHIFA_USER_INFO, localStorage.getItem(AppUtils.DEFAULT_INSTITUTE) +":"+
                    localStorage.getItem(AppUtils.PERSON_CODE));
                }
      }else{
        customReq = req.clone({
          headers: req.headers.set('Authorization','Basic '+ basicheader)
      })
      }
        return customReq;
    }
     handle400Error(error) {
         console.log("400 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 EmptyObservable.create();
    }

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

    let customReq: any;
    let client_id = 'test'; 
    let client_secret= 'secret';
    let basicheader = btoa(client_id +':'+ client_secret);
    auth.refreshToken().subscribe((token) => {
                    console.log("token " +JSON.stringify(token));
                    if (token instanceof HttpErrorResponse) {
      if (token.status === 401) {
console.log("error");
      }
                    }
                    if (token) {
                        localStorage.setItem(AppUtils.STORAGE_ACCOUNT_ACCESS_TOKEN, token["access_token"]);
                        localStorage.setItem(AppUtils.STORAGE_ACCOUNT_REFRESH_TOKEN, token["refresh_token"]);
                        localStorage.setItem(AppUtils.STORAGE_ACCOUNT_EXPIRES_IN, token["expires_in"]);
                        this.tokenSubject.next(token["access_token"]);
                        return next.handle(this.addToken(req));
                    }
                    console.log("refresh failed");
                    // If we don't get a new token, we are in trouble so logout.
                     this.logoutUser();
                     return EmptyObservable.create();
              }, (err) => {
                    console.log("error  2" +err);
                    // If there is an exception calling 'refreshToken', bad news so logout.
                     this.logoutUser();
                      return EmptyObservable.create();
              },() => { 
                    console.log("token finally)");
                    this.isRefreshingToken = true;
                });
              //  )
        } else {
            console.log("this.tokenSubject "+ this.tokenSubject);
            console.log("this.tokenSubjec2 "+ this.tokenSubject.filter(token => token != null));
            return this.tokenSubject
                .filter(token => token != null)
                .take(1)
                .switchMap(token => {
                    return next.handle(this.addToken(req));
                });

        }
    }

 logoutUser(){
     swal({
            title: 'Session Expired',
            text: 'your session has been expired please re login',
            timer: 5000,
            onOpen: () => {
              swal.showLoading()
            }
          }).then((result) => {
            if (result.dismiss === 'timer') {
              this.router.navigate([AppUtils.BACKEND_API_AUTHENTICATE_PATH]);
              window.location.reload();
            }
          })
   localStorage.clear();
   this.router.navigate([AppUtils.BACKEND_API_AUTHENTICATE_PATH]);
  // window.location.reload();
   //return Observable.throw("");
 }

这是验证服务类

 import { Injectable, Component, EventEmitter } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpClient, HttpResponse, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import 'rxjs/add/operator/map';
import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/retry';
import * as AppUtils from '../common/app.utils';
import { Router } from '@angular/router';
import { SharedService } from '../common/services/shared.service';
import 'rxjs/add/operator/catch';
declare var swal: any;
@Injectable()
export class AuthService {
  cachedRequests: Array<HttpRequest<any>> = [];
  constructor(private router: Router, private http : HttpClient) {
  }
  refreshToken(): Observable<any>{
    let client_id = 'irsauth'; 
    let client_secret= 'secret';
    let basicheader = btoa(client_id +':'+ client_secret);
    let headers = new HttpHeaders();
    headers.set('Authorization', 'Basic ' + basicheader);
    return this.http.get(AppUtils.REFRESH_TOKEN + localStorage.getItem(AppUtils.STORAGE_ACCOUNT_REFRESH_TOKEN), { headers: headers })
    .catch((e: any) => Observable.throw(this.errorHandler(e)))

  }
 errorHandler(error: any): void {
   console.log("auth error")
   Observable.throw("");
  }

 logoutUser(){
       localStorage.clear();
   this.router.navigate([AppUtils.BACKEND_API_AUTHENTICATE_PATH]);
  // window.location.reload();
   //return Observable.throw("");
 }
}

}

这对我有用。检查这是否有帮助。基本上,它是Angular HTTP服务上的包装器。

callHttpGet(url: string) {
  let headers = new Headers({ 
          "Content-Type": "application/json", 
          "Authorization": "Bearer " + 
          localStorage.getItem("accessToken") 
  });
  let options = new RequestOptions({ headers: headers });
  var me = this;
  return this.http.get(url, options)
    .catch(initialError => {
      if (initialError && 
            initialError.status === 401 && 
            initialError.json()["message"] === "Token expired") {
        // token might be expired, try to refresh token
        var tokenObject = new Object();
        tokenObject["token"] = localStorage.getItem("refreshToken");
        return me.authenticatorService.authenticate(tokenObject)
          .flatMap(res => {
            return me.http.get(url, me.options);
          })
          .catch(error => {
            if (error && 
                    error.status === 401 && 
                    (error.json()["message"] === "Refresh token expired" || 
                    error.json()["message"] === "Token expired")) {
              localStorage.clear();
              this.router.navigate(['/login']);
              return Observable.throw(error);
            }
            else {
              return Observable.throw(error);
            }
          });
      }
      else {
        return Observable.throw(initialError);
      }
    });
}

最新更新