angular - 在Angular http拦截器中刷新令牌后重试请求
问题描述
我有 401 拦截器,当 access_token 过期时,一个请求成功。拦截器重新加载令牌并返回 next.handle(customReq)。但是当同时有 2 个或多个请求并且两个请求都已过期令牌时,我遇到了问题,因为第二个请求尝试再次刷新,但现在刷新令牌无效。所以....我试图设置一个标志只做一次,并使用自定义的 observable 返回。问题是组件现在永远不会成功与否,而且我无法删除加载程序。
http拦截器:
return next
.handle(customReq).pipe(
tap((ev: HttpEvent < any > ) => {
if (ev instanceof HttpResponse) {
this.setApiStatus(ApiStatusCode.ACTIVE);
this.interceptorIgnore.removeIgnore(request.url);
}
}),
catchError(resp => {
if (resp instanceof HttpErrorResponse) {
switch (true) {
// Unauthorized
case resp.status === 401:
return this.attemptToRefreshToken(apiRequest, customReq, next);
// More code unnecessary ....
}
}
return throwError(resp);
})
);
tryToRefreshToken 方法:
attemptToRefreshToken(apiRequest: ApiRequest, customReq: HttpRequest<any>, next: HttpHandler) {
const retryRequest = () => {
this.updatingToken = false;
customReq = customReq.clone({
headers: apiRequest.buildHeader()
});
return next.handle(customReq);
};
if (!this.updatingToken) {
this.updatingToken = true;
const tokenRequestData = this.apiAuth.refreshTokenData();
return this.http.request(tokenRequestData.opts.method, tokenRequestData.url, tokenRequestData.opts)
.pipe(flatMap((token: ResponseTokenFormat) => {
ApiAuth.storedToken = token;
this.usersService.queryUsersUsename(ApiAuth.storedUser).then(([user]) => {
if (user && !user.isAdmin) {
this.sessionService.setUserPermissions(user);
}
});
this.tokenUpdated.next();
return retryRequest();
}));
}
return this.tokenUpdated$.pipe(
flatMap(() => retryRequest())
);
}
retryRequest 在调用 next() 时执行并且工作正常,但它从未通知服务女巫调用此 http 请求。返回retryRequest(); 当我刷新令牌时,它可以正常工作并且服务可以订阅。
我做错了什么?也许是可观察的?
解决方案
我认为您可能必须在 attemptToRefreshToken 中使用exhaustMap而不是flatMap。
它们是如何工作的?
- flatMap:立即为任何源项目创建一个 Observable,所有以前的 Observable 都保持活动状态
- excludeMap:源项被忽略,而前一个 Observable 未完成。
推荐阅读
- javascript - 如何将一些对象键仅推送到反应js中的另一个数组中
- python-3.x - 在 Keras (Python) 中使用神经网络进行样本外预测
- python - 安装opencv时出现错误
- gatsby - 将优惠券添加到 Stripe Checkout 或 allow_promotion_codes: true on redirectToCheckout
- python - 同时运行异步任务
- java - 带有 Spring Boot 2.3 的 Jpos Q2 服务器
- r - 按组和列之间查找最小值
- solr - Solr zookeeper 状态问题(null:java.io.UncheckedIOException: java.net.SocketException: Connection reset)
- amazon-web-services - health-check-grace-period-seconds 覆盖默认值还是仅将值应用于命令?
- matlab - 将 Matlab 函数转换为 Simulink 函数时出现问题