我的应用程序使用 JWT token
向后端进行身份验证。我有一个 Angular Interceptor
可以捕获 http 调用中的任何错误。此拦截器检查调用是否返回 401 Unauthorized
响应,如果是,它会调用端点以刷新 token ,然后再次重试原始调用。
我的问题是,出于某种原因,对 refreshToken 端点的调用被执行了两次。
这是我的拦截器(为简洁起见进行了编辑):
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError((error: any) => {
switch (error.status) {
// unauthorized
case 401:
// the token is stored in an NGRX store, so retrieve it first
return this.userStore.pipe(select(fromUser.getUserAccessToken)).pipe(
take(1),
mergeMap(userToken => {
if (userToken) {
// token exists but may be invalid, try to refresh
return this.userService.refreshToken(userToken).pipe(
switchMap(refreshedToken => {
if (refreshedToken) {
...
} else {
// token was not refreshed, delete session
...
}
})
);
}
})
);
}
})
);
}
return this.userService.refreshToken(userToken)
是执行两次的语句(使用相同的原始 token ),因此第一次调用刷新将通过,第二次调用将通过显然失败了,因为它试图再次刷新相同的 token ,导致用户 session 被删除。
有什么想法吗?
更新:
我还在研究这个。我在我的代码中放置了一堆断点和 console.log
:
catchError((error: any) => {
>>>>> console.log('1');
switch (error.status) {
case 401:
return this.userStore.pipe(select(fromUser.getUserAccessToken)).pipe(
take(1),
mergeMap(userToken => {
>>>>> console.log('2');
if (userToken) {
return this.userService.refreshToken(userToken).pipe(
switchMap(refreshedToken => {
>>>>> console.log('3');
Console.log
#1 和 #2 只被打印到控制台一次,这意味着 http 错误
只被捕获一次。但是 #3 被打印了两次,我认为这意味着对刷新端点的调用被调用了两次,或者 observable 以某种方式返回了两个值?
最佳答案
不确定为什么,但似乎 refreshToken
输出了多个值。这可以通过 take
运算符轻松解决。像这样:
return this.userService.refreshToken(userToken).pipe(
take(1),
switchMap(refreshedToken => {
>>>>> console.log('3');
关于Angular HTTP 拦截器执行内部 http 请求两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64921894/