当我的拦截器根据 JWT 过期拦截请求时,我遇到了麻烦。我能够执行令牌的刷新,但原始请求永远不会再次重试。
我有以下错误拦截器,除了重试原始请求代码(complete() 内部的部分)之外,它运行良好。 它在完整方法内执行警报和控制台日志,因此执行会一直进行到那里,但永远不会重试原始请求。
export const ErrorInterceptorMethod: HttpInterceptorFn = (
req: HttpRequest<unknown>,
next: HttpHandlerFn,
) => {
const loginService = inject(LoginService);
return next(req).pipe(
catchError ( error => {
if (error.status === 401 && req.url !== environment.urlApiAdmin + '/login') {
// Unauthorized - JWT Token expired
console.log("Performing refreshToken request!");
let reqCloned = req.clone();
loginService.refreshToken().subscribe({
error: (errorData) => {
console.error(errorData);
console.log("Error refreshing token, logout");
loginService.logout();
},
complete: () => {
alert("Refresh done, execute again the request!");
console.log(reqCloned);
return next(reqCloned); // THIS IS NEVER EXECUTED / DOES NOTHING
}
});
}
if (error.status === 403) {
console.log("403 error");
loginService.logout();
}
return throwError(() => error);
})
)
};
我一直在寻找选项,但找不到任何有用的东西,因为找到的所有示例都使用 HttpHandler 而不是 HttpHandlerFn。
HttpHandlerFn没有.handle方法,所以我找不到有效的方法来实现它。
我还尝试在拦截器之外(在外部服务中)执行此请求,但我无法做到这一点。
有人可以指出我正确的方向吗?
干杯!
伙计们,我已经设法用以下代码解决了这个问题:
if (error.status === 401 && req.url !== environment.urlApiAdmin + '/login') {
// Unauthorized - JWT Token expired
return loginService.refreshToken().pipe(
switchMap((tokenReceived) => {
console.log(tokenReceived);
sessionStorage.setItem("token", tokenReceived.token);
loginService.currentAdminToken.next(tokenReceived.token);
loginService.currentAdminLoginOn.next(true);
let token : String = tokenReceived.token;
if (token != '') {
req = req.clone({
setHeaders: {
'Accept' : 'application/json',
'Authorization' : `Bearer ${token}`,
},
})
}
return next(req);
}
));
}
问题的关键是调用refreshToken方法,将响应带回管道内 - > switchMap,然后返回原始请求并更改其令牌。
希望这也能帮到你。
干杯