javascript - Angular 4 インターセプターが 401 エラー時に各リクエストではなく一度だけトークンをリフレッシュする
トークンを更新したいです。インターセプターを使用しています:
アプリ.interceptor.ts
import { Observable } from 'rxjs';
import { Injectable, Inject, Injector } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { UserService } from "./user/services/user.service";
@Injectable()
export class AngularInterceptor implements HttpInterceptor {
public userService;
constructor(private injector: Injector) {
}
private applyCredentials = function (req) {
return req.clone({
headers: req.headers.set('Authorization', 'Bearer ' + localStorage.getItem('token'))
});
};
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.userService = this.injector.get(UserService);
return next.handle(this.applyCredentials(req))
/*.do(event => {
if (event instanceof HttpResponse) {
console.log(event);
}
})*/
.catch((res) => {
console.log('Token refresh');
if (res.status === 401 || res.status === 403 || res.status === 500) {
return this.userService.refreshToken().first().flatMap((data: any) => {
console.log(data.data);
if (data.data !== '') {
localStorage.removeItem('token');
localStorage.setItem('token', data.data);
this.userService.token = localStorage.getItem('token');
this.userService.isAuthenticated = true;
} else {
this.userService.logOut();
return Observable.throw(res);
}
return next.handle(this.applyCredentials(req));
});
}
/*else if (res.status === 500) {
this.userService.logOut();
}*/
return Observable.throw(res);
});
}
}
私のトークンはリフレッシュされており、動作しています。しかし、問題があります。複数のリクエストがある場合、私のトークンはリフレッシュされ、またリフレッシュされ、さらにリフレッシュされます。もしリクエストが3つあると、トークンは3回リフレッシュされます。
私の component.ts では:
Observable.forkJoin(
this.countryService.getCountries(),
this.movieService.getMovies(),
this.userService.getUsers()
).subscribe(
data => {
console.log(data[0]);
console.log(data[1]);
console.log(data[2]);
...
this.initPage();
},
err => console.error(err)
)
私のトークンは三回更新されました。すべてのリクエストを読み込み、その後で initPage() 関数を実行したいです。
私はトークンを一度だけ更新して、その後すべてのリクエストを再送したいです。