Я делаю перехватчик JWT для обработки ошибки 401. Моя идея собрать все исходные запросы после 401 в массив, затем обновить sh мой токен, а затем добавить новый заголовок к моему запросу. Вот код:
type CallerRequest = {
subscriber: Subscriber<any>;
failedRequest: HttpRequest<any>;
};
@Injectable()
export class RefreshTokenInterceptor implements HttpInterceptor {
private refreshInProgress: boolean;
private requests: CallerRequest[] = [];
constructor(
public authService: AuthService,
public customersService: CustomersService,
private http: HttpClient
) {
this.refreshInProgress = false;
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (!req.url.includes('api/')) {
return next.handle(req);
}
const observable = new Observable<HttpEvent<any>>((subscriber) => {
const originalRequestSubscription = next.handle(req)
.subscribe((response) => {
subscriber.next(response);
},
(err) => {
if (err.status === 401) {
this.handleUnauthorizedError(subscriber, req);
} else {
subscriber.error(err);
}
},
() => {
subscriber.complete();
});
return () => {
originalRequestSubscription.unsubscribe();
};
});
return observable;
}
private addToken(request: HttpRequest<any>, token: string) {
return request.clone({setHeaders: {'Authorization': `Bearer ${token}`}});
}
private handleUnauthorizedError(subscriber: Subscriber<any>, request: HttpRequest<any>) {
this.requests.push({ subscriber, failedRequest: request });
if (!this.refreshInProgress) {
this.refreshInProgress = true;
console.log('go refresh');
this.authService.refreshToken()
.pipe(
finalize(() => {
this.refreshInProgress = false;
})
)
.subscribe(
result => {
console.log(result); // <-- I cannot get here
this.repeatFailedRequests(this.authService.getAccessToken());
},
err => {
console.log(err); // <-- And cannot get here
}
)
}
}
private repeatFailedRequests(authHeader: string) {
this.requests.forEach((c) => {
const requestWithNewToken = this.addToken(c.failedRequest, authHeader);
this.repeatRequest(requestWithNewToken, c.subscriber);
});
this.requests = [];
}
private repeatRequest(requestWithNewToken: HttpRequest<any>, subscriber: Subscriber<any>) {
this.http.request(requestWithNewToken).subscribe((res) => {
subscriber.next(res);
},
(err) => {
if (err.status === 401) {
this.authService.removeTokens();
}
subscriber.error(err);
},
() => {
subscriber.complete();
});
}
}
Посмотрите мой метод handleUnauthorizedError. Я не могу получить там результаты.
Кстати, вот мой refreshToken:
refreshToken() {
return this.post('api/v0/jwt/refresh/', {refresh: this.getRefreshToken()})
.pipe(tap((tokens: Tokens) => {
this.storeTokens(tokens);
}));
}
Что я делаю не так и как мне решить эту проблему надлежащим образом? путь? Спасибо!
ДОБАВЛЕНО :
Если я попробую перехватчик JWT из этого вопроса Angular 4 Запросы на повторную попытку перехватчика после обновления токена sh (самый популярный ответ) У меня та же проблема - мои результаты от RefreshToken () не обрабатываются.