Мне нужно обновить токен в HttpInterceptor перед выполнением запроса, для этого я проверяю токен доступа перед запросом и вызываю обновление, если срок его действия истек.В настоящее время мой перехватчик выглядит следующим образом:
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
private refreshTokenSubject = new BehaviorSubject(null);
private refreshTokenObservable = this.refreshTokenSubject.asObservable();
private isRefreshingToken = false;
constructor(private authService: AuthService) {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const tokenData = AuthService.getCurrentSessionData();
if (!this.isRefreshingToken) {
// if no token set - make request as-is
const tokenSet = tokenData && tokenData.token;
if (!tokenSet) {
return next.handle(request);
}
// proceed if token not expired
const tokenExpired = new Date(tokenData.expirationDate) < new Date();
if (!tokenExpired) {
return next.handle(this.setAuthHeader(request, tokenData.token));
}
// check if we can refresh the token and logout instantly if not
const tokenRefreshable = tokenData.refreshToken && new Date(tokenData.refreshTokenExpirationDate) > new Date();
if (!tokenRefreshable) {
this.authService.logout();
return Observable.throw('');
}
this.isRefreshingToken = true;
// make all subsequent requests wait for new token
this.refreshTokenSubject.next(null);
// make refresh request
return this.authService.refreshToken()
.switchMap((res: any) => {
AuthService.storeSessionData(res, Utils.getLocalStorageItem(STORAGE_KEYS.STAY_LOGGED_IN));
this.isRefreshingToken = false;
// let subsequent awaiting proceed
this.refreshTokenSubject.next(res.access_token);
return next.handle(this.setAuthHeader(request, res.access_token));
})
.catch((err) => {
this.authService.logout();
return Observable.throw('');
})
.finally(() => {
this.isRefreshingToken = false;
});
} else {
// if token refreshing in progress - wait for new token
return this.refreshTokenObservable
.filter(token => token !== null)
.take(1)
.switchMap((token) => {
return next.handle(this.setAuthHeader(request, token));
});
}
}
private setAuthHeader(request, token) {
return request.clone({
setHeaders: {
Authorization: `Bearer ${token}`,
},
});
}
}
Проблема в том, что this.authService.refreshToken()
никогда не выполняет запрос, а последующие запросы никогда не выполняются.Я думаю, это потому, что ничто не подписывается на наблюдаемое, возвращаемое из HttpClient, вот код метода refreshToken
:
public refreshToken() {
const tokenData = AuthService.getCurrentSessionData();
return this.http.post(
`${environment.apiPath}/auth/refresh`,
{ refresh_token: tokenData.refreshToken },
);
}
Как я могу исправить этот код, чтобы сделать запрос refreshToken
и позволить другим запросам продолжаться после негокак задумано?