在刷新auth.interceptor.ts
中的JWT令牌时,我试图捕获BadRequest(400),因为刷新令牌应在某个时刻过期。您可以查看下面的代码段,但是我也可以提供StackBlitz。
问题来自catchError
,当我在其中进行return this.authService.logout()
时。它进入无限循环,因为当我在switchMap中执行return next.handle(request);
时,它继续向/api/values
(实际请求)授予用户未授权,并引发了另一个错误。我做return throwError(error);
时也是如此。这就是无限循环发生的地方。我确实必须订阅this.authService.logout()
,因为注销用户后,我将从数据库中撤消了他的刷新令牌(HTTP帖子)。您可以在StackBlitz上看到整个代码。
return this.authService.refreshToken()
.pipe(
switchMap(token => {
console.log('Token refreshed.');
return next.handle(this.attachTokenToRequest(request, token));
}),
catchError(error => {
return this.authService.logout()
.pipe(
switchMap(result => {
console.log(result);
return throwError(error); // request = /api/values, error = /api/refresh/token
// return next.handle(request);
})
)
})
);
除了上面的内容以外,我尝试使用下面的代码捕获错误代码400,但还是一样。
if (error.status === 400 && error.error === "Cannot find that refresh token." || error.error === "Expired refresh token.") {
console.log('400 bad request');
return this.authService.logout()
.pipe(
switchMap(error => {
return Observable.throw(error); // this should be replaced, maybe?
})
);
}
如上所述,我知道问题出在哪里。我不知道该如何解决。我想捕获刷新令牌何时到期或根本不存在,然后注销用户并导航到登录页面。我该怎么办?
答案 0 :(得分:3)
您需要向后端服务器旁路拦截器发出登出请求。因此,您可以使用HttpClient
创建一个新的HttpBackend
,并在不希望拦截器干扰请求的情况下使用它。
@Injectable()
export class AuthService {
private backendClient: HttpClient;
public constructor(private httpClient: HttpClient, handler: HttpBackend) {
this.backendClient = new HttpClient(handler);
}
// this API uses interceptors
public refreshToken() {
return this.httpClient.get(....);
}
// this API does not use interceptors
public logout() {
return this.backendClient.get(....);
}
}