如果当前api给401或令牌到期错误,我想基于刷新令牌获得新的令牌。
下面的代码是我的拦截器
当我尝试在catch错误部分中调用api(API.refreshToken)时,浏览器立即将其取消。就像下面的图片
我的代码如下。
import { Injectable } from "@angular/core";
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpClient,
HttpHeaders,
HttpErrorResponse
} from "@angular/common/http";
import { Observable, BehaviorSubject } from "rxjs";
import { helpers } from "chart.js";
import { API } from "../constants/apiConstants";
import { AuthService } from "../services/auth.Service";
import { Router } from "@angular/router";
import { catchError, flatMap } from "rxjs/operators";
import { switchMap } from "rxjs-compat/operator/switchMap";
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
private refreshTokenInProgress = false;
// Refresh Token Subject tracks the current token, or is null if no token is currently
// available (e.g. refresh pending).
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(
null
);
constructor(
private _auth: AuthService,
private _router: Router,
private httpClient: HttpClient
) {}
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
// add authorization header with basic auth credentials if available
let token = this._auth.getLocalStorageItem("accesstoken");
if (token) {
let helpersData = {};
helpersData[API.idToken] = `${this._auth.getLocalStorageItem(
"identityToken"
)}`;
if (request.url.includes("refreshtoken")) {
helpersData[API.refereshTokenHeader] = this._auth.getLocalStorageItem(
"refreshToken"
);
} else {
helpersData[API.authorization] = token;
helpersData[API.appclientidKey] = API.appClientIdValue;
helpersData[API.userpoolIdKey] = API.userpoolIdValue;
}
request = request.clone({
setHeaders: helpersData
});
}
return next.handle(request).pipe(
catchError(error => {
// NOTE: We don't want to refresh token for some requests like login or refresh token itself
// So we verify url and we throw an error if it's the case
console.log("error", error);
console.log("request", request);
if (this.refreshTokenInProgress) {
console.log("in refresh token on");
// If refreshTokenInProgress is true, we will wait until refreshTokenSubject has a non-null value
// – which means the new token is ready and we can retry the request again
return this.refreshTokenSubject
.filter(result => result !== null)
.take(1)
.switchMap(() => next.handle(this.addAuthenticationToken(request)));
} else {
this.refreshTokenInProgress = true;
console.log("in refresh token off");
// Set the refreshTokenSubject to null so that subsequent API calls will wait until the new token has been retrieved
this.refreshTokenSubject.next(null);
//Generate params for token refreshing
// Call auth.refreshAccessToken(this is an Observable that will be returned)
return this.httpClient
.get<any>(API.refreshToken)
.catch((err: any) => {
console.log("catch error", err);
this.refreshTokenInProgress = false;
this._auth.logout();
return Observable.throw(error);
})
.pipe((resData:any) => {
console.log("rdata", resData);
// If reload successful update tokens
if (resData.status == 200) {
let rData = resData.data.AuthenticationResult;
//Update tokens
this._auth.setLocalStorageItem(
"accesstoken",
rData.AccessToken
);
this._auth.setLocalStorageItem(
"identityToken",
rData.IdToken
);
//Clone our fielded request ant try to resend it
this.refreshTokenInProgress = false;
this.refreshTokenSubject.next(token);
return next.handle(this.addAuthenticationToken(request));
} else {
//Logout from account
this._auth.logout();
return Observable.throw(error);
}
});
}
// return Observable.throw("not user found");
})
);
}
addAuthenticationToken(request) {
// Get access token from Local Storage
let helpersData = {};
helpersData[API.authorization] = this._auth.getLocalStorageItem(
"accesstoken"
);
helpersData[API.idToken] = `${this._auth.getLocalStorageItem(
"identityToken"
)}`;
// If access token is null this means that user is not logged in
// And we return the original request
// if (!token) {
// return request;
// }
// We clone the request, because the original request is immutable
return request.clone({
setHeaders: helpersData
});
}
}