angular - 试图在 http 拦截器中捕获 401,刷新我的会话并重试原始请求
问题描述
我正在尝试拦截来自 的响应/api
,如果它们是 401,则捕获它们,执行刷新会话操作,然后再次重试原始 HTTP 调用(另外,如果它再次出现 401,则防止它无限循环)
我认为我在下面的代码中正在做的是使用 http 处理程序触发请求,订阅其事件,如果它在 401 上失败,则刷新然后返回一个可观察的克隆请求正在被处理程序操作。
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (!request.url.startsWith('/api')) {
return next.handle(request)
}
const cloned = request.clone()
return next.handle(request)
.pipe(
catchError((error: any) => {
if (error.status !== 401) {
return throwError(error)
}
return from(this.sessionService.refresh())
.pipe(map(() => next.handle(cloned)))
})
)
}
关于如何实现我想要的目标的任何建议?
解决方案
答案是使用switctMap
而不是map
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
{
if (!request.url.startsWith('/api')) {
return next.handle(request)
}
const cloned = request.clone()
return next.handle(request)
.pipe(
catchError((error: any) => {
if (error.status !== 401) {
return throwError(error)
}
return from(this.sessionService.refresh())
.pipe(switchMap(() => next.handle(cloned)))
})
)
}
但是,我选择了另一种方法,在请求发生之前检查我是否有会话,如果需要,注入刷新操作。
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (
!request.url.startsWith('/api') ||
this.sessionService.isValid
) {
return next.handle(request)
}
return from(this.sessionService.refresh())
.pipe(switchMap(() => next.handle(request)))
}
推荐阅读
- selenium - SocketTimeoutException:使用 TeamCity 的 RestAssured 连接超时
- swift - S 的 (Swift) 扩展
> 其中 S 是泛型结构,P 是类型约束协议 - css - 如何创建这样的面包屑导航?
- http - 如何使这个 HTTP 请求示例工作?
- delphi - 当 TGridPanel 的单元格具有较大的 BorderWidth 时,如何从它获取真正的 ClientRect?
- java - Grails 4.X 可以运行哪些 Java 版本?
- r - ggplot中多列的饼图
- graphql - graphQL + gatsby:查询 Image 或 mp4 的字段
- java - 蓝牙未与其他设备自动配对
- c# - Web 应用程序用户身份验证的最安全方式