我正在使用JWT,并且我有以下逻辑:
此过程必须对用户隐藏。我已经捕获了401状态代码,并在检索新令牌后重复了原始调用,问题是将结果返回到原始调用。 这是带有http请求的服务:
getListCategories(){
return this.http.get<Category[]>("/api/configuration/category").pipe(
catchError(err => this.handleError.handleError(err, { severity: 'error', summary: 'Error retrieving the list of categories', life: 5000 }))
);
}
这是进行刷新调用并重复原始调用的错误拦截器:
export class ErrorInterceptorService implements HttpInterceptor {
constructor(private auth: AuthService, public router: Router) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const { shouldRetry } = this;
return next.handle(request).pipe(
retryWhen(genericRetryStrategy({
shouldRetry
})),
catchError(err => {
//401 the token is invalid so I have to refresh it
if (err.status === 401 && request.url !== "/api/login") {
this.auth.refreshToken().subscribe(
(apiResult: SessionTokenResponse) => {
this.auth.saveToken(apiResult.token);
request = request.clone({ headers: request.headers.set('Authorization', 'Bearer ' + apiResult.token) });
next.handle(request).subscribe();
},
);
} else if (err.status === 401 && request.url === "/api/login") {
this.auth.logout()
}else{
const error = err.error.message || err.statusText;
return throwError(error);
}
}),
)
}
private shouldRetry = (error) => (error.error instanceof ErrorEvent);
}
问题出在服务中,它不等待remake调用,而是在出现第一个错误后退出。你能帮我吗?谢谢
答案 0 :(得分:1)
您想通过链式操作返回Observable
,该链式操作包括原始请求和重复请求之间的额外请求。我会尝试使用switchMap
来做到这一点。
会是这样的:
catchError(err => {
if (err.status === 401 && request.url !== "/api/login") {
//by returning observable here, you are "chaining" the calls so original caller will get this observable's result. `catchError` can be threated like `catch` block in `try-catch` where you can still do operations and return results - ergo continue operations.
return this.auth.refreshToken()
.switchMap( // this just switches from one observable to another
(apiResult: SessionTokenResponse) => {
this.auth.saveToken(apiResult.token);
request = request.clone({ headers: request.headers.set('Authorization', 'Bearer ' + apiResult.token) });
return next.handle(request); // return original request handler with updated headers
},
);
显然未经测试,语法可能无效,如此处所述。