【发布时间】:2019-12-12 22:06:49
【问题描述】:
我正在做 Angular 8 应用程序,我正在尝试实现 Angular http 拦截器重复请求。我想拦截我对 WebAPI 的所有 UI 请求,当我的令牌过期时,刷新令牌并召回所有被拒绝的请求。 我实现了代码:
import { Inject, Injectable, Injector } from '@angular/core';
import {
HttpInterceptor,
HttpRequest,
HttpResponse,
HttpHandler,
HttpEvent,
HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError, from, Subject } from 'rxjs';
import { tap, map, catchError } from 'rxjs/operators';
import { StorageSvc } from '../factories/storageSvc';
import { SysSettings } from '../constant/sysSettings';
import { SingletonRootClass } from '../../../src/app/shared/singleton-root';
import { AuthService } from './authService';
import { Router } from '@angular/router';
@Injectable()
export class InterceptService implements HttpInterceptor {
refreshTokenInProgress = false;
tokenRefreshedSource = new Subject();
tokenRefreshed$ = this.tokenRefreshedSource.asObservable();
constructor(@Inject(StorageSvc) public storageSvc: any,
@Inject(AuthService) public authService: any,
private router: Router,
private injector: Injector
) { }
addAuthHeader(request) {
const authData = this.storageSvc.retrieve('authorizationData');
const language = authData && authData.profile
? { languageCode: authData.profile.laguageCode, regionCode: authData.profile.regionCode }
: this.getDefaultLanguage();
const headers = {
'Accept-Language': this.buildAcceptLanguageHeader(language.languageCode, language.regionCode),
'NotificationConnectionId': SysSettings.NotifyConnectionId
};
if (authData) {
headers['Authorization'] = 'Bearer ' + authData.token;
headers['UserName'] = authData.userName;
}
request = request.clone({
setHeaders: headers
});
return request;
}
// intercept request and add token
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<any> {
request = this.addAuthHeader(request);
// Handle response
return next.handle(request).pipe(
map((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
console.log('event--->>>', event);
}
return event;
}),
catchError((error: HttpErrorResponse) => {
if (error.status === 401) {
return this.refreshToken()
.switchMap(() => {
request = this.addAuthHeader(request);
return next.handle(request);
})
.catch(() => {
this.authService.logOut();
this.router.navigate(['/login']);
});
}
return throwError(error);
})
);
}
refreshToken() {
if (this.refreshTokenInProgress) {
return new Observable(observer => {
this.tokenRefreshed$.subscribe(() => {
observer.next();
observer.complete();
});
});
} else {
this.refreshTokenInProgress = true;
return this.authService.refreshToken()
.do(() => {
this.refreshTokenInProgress = false;
this.tokenRefreshedSource.next();
});
}
}
sleep(ms = 0) {
return new Promise(r => setTimeout(r, ms));
}
getDefaultLanguage() {
// const savedLanguage = this.storageSvc.retrieve('language');
const savedLanguage = SingletonRootClass.getInstance().defaultLang;
// Region code not used for now
const language = { languageCode: savedLanguage ? savedLanguage : 'en', regionCode: 'CA' };
return language;
}
buildAcceptLanguageHeader(languageCode, regionCode) {
return languageCode + '-' + regionCode + ',' + languageCode + ';' + 'q=0.8,en;q=0.6';
}
}
但我无法自动回忆被拒绝的请求。在我的截图上:GetNotifications、GetNotificationTypes 和 GetEventTypes
任何人都可以推荐拦截器的角度解决方案来召回在刷新令牌时同时被拒绝的所有请求吗? 谢谢你
【问题讨论】:
标签: angular typescript rxjs