尝试在http拦截器中捕获401,刷新我的会话并重试原始请求
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尝试在http拦截器中捕获401,刷新我的会话并重试原始请求相关的知识,希望对你有一定的参考价值。
我试图拦截从/api
返回的响应,捕获它们,如果它们401,执行刷新会话操作,然后再次重试原始HTTP调用(另外防止它无限循环,如果它再次401s)
我认为我在下面的代码中正在做的是使用http处理程序触发请求,订阅它的事件,如果它在401上失败,则刷新然后返回由处理程序执行的克隆请求的observable。
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)))
})
)
}
关于如何实现我的目标的任何建议?
答案
可能有一些语法错误,因为我正在从移动设备写作,但这应该让你开始
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)
.do((event: HttpEvent<any>) =>
return from(this.sessionService.refresh())
.pipe(map(() => next.handle(cloned)))
}), (err: any) => {
if (err instanceof HttpResponse) {
if(err.status === 401){
return throwError(error);
}
}
)
}
另一答案
答案是使用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)))
}
以上是关于尝试在http拦截器中捕获401,刷新我的会话并重试原始请求的主要内容,如果未能解决你的问题,请参考以下文章