我正在使用HttpInterceptor将访问令牌应用于传出的httprequests。拦截器调用返回Observable的getUser(),将accesstoken添加到请求中。这一切都很好,花花公子。但是我现在想要的是,如果请求返回401,我想刷新令牌,然后再次处理请求。因此,我发现了所有错误,并调用了renewToken,它也返回了Observable。但是问题在于它似乎无法访问renewToken的回调函数。因此,刷新的令牌永远不会应用,并且api调用也永远不会重新执行,但是,renewToken出现在我的网络标签中,并且成功。
我通过用renewToken()替换第一个getUser()调用来确保renewToken()确实有效,并且可以正常工作。所以我的猜测是,我对rxjs的困惑以及如何链接长管道等是这出了问题的地方。
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
if (request.url.includes(environment.apiBaseUrl)) {
return this.authService.getUser().pipe(
mergeMap((user: User) => {
console.log('in getUser call ' + user.expires_in);
if (user) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${user.access_token}`
}
});
}
return next.handle(request).pipe(
tap(
() => {},
(err: any) => {
debugger
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
return this.authService.renewToken().pipe(
mergeMap((renewedUser: User) => {
console.log('in renewToken call');
if (renewedUser) {
console.log(renewedUser.expires_in);
request = request.clone({
setHeaders: {
Authorization: `Bearer ${
renewedUser.access_token
}`
}
});
}
return next.handle(request).pipe(
tap(
() => {},
newErr => {
console.log(newErr);
this.authService.login();
}
)
);
}),
catchError(renewError => {
return Observable.throw(renewError);
})
);
}
}
}
)
);
})
);
} else {
return next.handle(request);
}
}
因此,如果我在第一个请求上未经授权,我想刷新令牌并重做请求,但是我从未输入renewToken()的回调函数来添加新的accesstoken并重做请求。
此外,理想的情况是对用户使用过期属性,如果过期,则刷新令牌,然后仅处理请求一次,但是我不知道如何异步实现。
编辑:我很确定这与以下事实有关:我无法以我认为可以通过点击功能返回的方式返回某些内容。因此,当尝试返回renewToken或next.handle时,这是不可能的。尽管如此,如果第一个请求返回错误,我不知道如何实际更新令牌并使用新令牌重做请求
答案 0 :(得分:0)
我设法通过用catchError替换tap来解决我的问题,为什么我不确定。如果有人知道,请解释。如果有人在发送第一个请求之前有一个想法,可以通过检查用户的expired属性来使其刷新,然后使其变得不安全,请告诉我。
return next.handle(request).pipe(
catchError((err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
return this.authService.renewToken().pipe(
mergeMap((renewedUser: User) => {
if (renewedUser) {
request = this.addBearerToken(
request,
renewedUser.access_token
);
}
return next.handle(request).pipe(
tap(
() => {},
newErr => {
console.log(newErr);
this.authService.login();
}
)
);
}),
catchError(renewError => {
return Observable.throw(renewError);
})
);
}
}
})
);