angular - 刷新 JWT 令牌后返回重新调用
问题描述
我正在使用 JWT,我有这个逻辑:
- 进行 http 调用
- 如果令牌过期或结果返回 401
- 返回 401 时,我必须进行 http 调用以要求新令牌
- 使用新令牌重新进行初始调用
- 返回结果
这个过程必须对用户隐藏。我已经捕获了 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);
}
问题出在服务中,它不等待重拍调用,而是在第一个错误后退出。你能帮我吗?谢谢
解决方案
您希望返回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
},
);
显然没有经过测试,并且可能是此处所写的语法无效。
推荐阅读
- angular - Angular 2 单元测试在它应该失败时总是通过
- python - 在pygame中同时检测两个CTRL
- tcl - TCL 中的全局数组
- permissions - Azure cosmos db 的资源令牌连接问题
- c# - 需要随机选择1个或3个
- oracle - 寻找好的在线 PL/SQL 练习和解决方案
- python - Google OAuth API 令牌请求出现 404 错误
- powershell - 登录后 Azure 凭据不可用
- python - 在使用 python optparse 设置默认值时检查是否传递了 arg
- batch-file - 在 IF 语句中对数组使用 DelayedExpansion 索引变量失败