- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正尝试在我的 Angular 前端实现 token 拦截器,但我当前的实现存在一个问题。
我的拦截器是这样的:
intercept(request: HttpRequest<any>,next: HttpHandler): Observable<HttpEvent<any>> {
if (request.headers.get("No-Auth") === "True") {
return next.handle(request);
}
return next.handle(request).pipe(
catchError(error => {
if (error instanceof HttpErrorResponse && error.status === 401) {
this.handle404Error(request, next);
} else {
return throwError(error);
}
})
);
}
和 handle404Error 函数:
handle404Error(request: HttpRequest<any>, next: HttpHandler) {
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);
return this.authService.refreshToken().subscribe(
(res: any) => {
if (Boolean(res) === true) {
this.isRefreshing = false;
this.refreshTokenSubject.next(res);
return next.handle(request);
} else {
return this.authService.logout();
}
},
err => {
return this.authService.logout();
},
() => {
this.isRefreshing = false;
}
);
} else {
return this.refreshTokenSubject.pipe(
filter(res => res != null),
take(1),
switchMap(() => {
return next.handle(request);
})
);
}
}
当我进行 API 调用并且服务器返回 404 时,我的拦截器将调用 /token
端点以获取新的 JWT。
请注意,我将 JWT 存储在服务器(内存中)的 session 对象中,而在客户端,我只有 sessionID 和刷新 token 作为 HttpOnly cookie。
问题是,当我进行 API 调用并且 JWT 无效时,它会设置新的 JWT,但不会再次发送之前的请求。 (JWT 过期后,我必须按两次按钮才能获取数据)。
你知道如何实现这个逻辑吗?
谢谢你的帮助。
最佳答案
第一件事是不对的——你在拦截器中订阅
,所以你得到了嵌套订阅,因为 Angular 在内部订阅了你的请求。
您真正想要的是从 catchError
返回您的 return next.handle(request);
。示例:
return next.handle(request).pipe(
catchError(error => {
if (error instanceof HttpErrorResponse && error.status === 401) {
return this.handle404Error(request, next);
} else {
return throwError(error);
}
})
);
handle404Error(request: HttpRequest<any>, next: HttpHandler) {
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);
return this.authService.refreshToken().pipe(
mergeMap((res: any) => {
if (Boolean(res) === true) {
this.isRefreshing = false;
this.refreshTokenSubject.next(res);
return next.handle(request);
} else {
/* return */ this.authService.logout();
return of(undefined) // added this because I dont know what this.authService.logout() returns. It must be an Observable
}
}),
catchError((err) => {
/* return */ this.authService.logout();
return throwError(err);
}))
} else {
return this.refreshTokenSubject.pipe(
filter(res => res != null),
take(1),
switchMap(() => {
return next.handle(request);
})
);
}
}
请注意,我没有检查任何拼写错误。我也丢弃了这个 block :
() => {
this.isRefreshing = false;
}
如果你想在 this.authService.refreshToken()
完成时执行它,你可以在 mergeMap
旁边添加 finalize
运算符并且catchError
.
解释这里实际发生的事情很简单 - 你从 intercept
方法返回 one Observable。只需将所有 API 调用通过管道连接在一起,返回的流就会执行它们。
关于javascript - token 拦截器不会再次发送原始请求(Angular、Node.js),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58937972/
我刚开始使用新的拦截方法,有一个基本问题,想知道如何在一个测试中链接下面的两个断言。 cy.intercept('GET', '/states').as('states'); cy.reload(tr
我有一个标签控件的自定义版本(使用用户控件构建)。在设计器中工作时,我想截取 Name 属性的设置(在属性面板中)并使用它来生成 Text 属性。也就是说,如果我在属性面板的 Name 属性中输入“l
嗨,我想通过 soapUI 解析 ssl soap 消息,而我试图通过 HttpMonitor 进行拦截它显示在异常下方 ERROR:Exception in request: javax.net.s
是否有可能从某个任意层拦截反向梯度,修改其值并继续反向传播回到网络的开始,根据您提供的修改后的梯度值更新所有先前层的反向梯度? 我知道你可以directly modify the gradients
我可以从什么 dll 中获得 Intercept 的扩展?我从 http://github.com/danielmarbach/ninject.extensions.interception 添加了
我有一个实现 onCreateOptionsMenu 方法的顶级 TabHost。我希望子 Activity (选项卡内的子 Activity )能够通过 onOptionsItemSelected
我在尝试反序列化 URL 时遇到此错误 Caused by: java.net.MalformedURLException: no protocol: www.boo.com at java.
首先,我是 Spring 的新手,这是我第一次尝试使用 Spring 编写基于 REST 的应用程序。 我计划在请求参数和响应中使用 Json。这让我想到两个问题。 有没有办法将 products="
在我基于 j_security_check 的登录表单中登录时一切正常。在这种情况下,我看到 JSESSIONID cookie 中的路径具有来自 URL 的值。但是当另一个登录页面构造动态表单(它正
我有一个我一直致力于下载文件的程序。一切正常,除非用户使用 AVG。奇怪的是,为了解决这个问题,似乎必须禁用 AVG 的“电子邮件保护”;将我的程序或 JRE 添加到异常(exception)列表不起
我正在寻找一种方法来挂接 SMSManager 或较低级别的机制,以便我可以在发送任何外发 SMS 消息之前拦截、读取和取消它们。 最佳答案 迟到总比不到好:) 我已经在这上面花了 2 天...并且不
我已成功拦截对 read() 的调用, write() , open() , unlink() , rename() , creat()但不知何故截获完全相同的语义stat()没有发生。我已经使用 L
阿里云ECS通过安全组屏蔽/拦截/阻断特定IP对云服务器的访问 所适用的场景: 通过安全组屏蔽、拦截、阻止特定IP对用户云服务器的访问,或者屏蔽IP访问服务器的特定端口。 配置的方法: 1、
我希望能够在类本身的构造函数中代理类的所有方法。 class Boy { constructor() { // proxy logic, do something before
使用 ajax 请求可以使用以下代码完成: let oldXHROpen = window.XMLHttpRequest.prototype.open; window.lastXhr = ''; wi
我想“拦截”/更改将 OData 与 Web API 一起使用时生成的 OData 查询..但我不完全确定如何“提取”生成的查询..我假设 OData 过滤器、扩展和更多一些如何生成某种表达式树或某种
当 JUnit 中的断言失败时,我想做一些“自己的事情”。我想要这个: public class MyAssert extends org.junit.Assert { // @Overrid
如何拦截 PartialFunction?例如在 Actor 中,如果我只想打印进入以下接收方法的所有内容,然后再将其传递给流程方法: class MyActor extends Actor {
我们正在使用 fluentvalidation(带有服务堆栈)来验证我们的请求 DTO。我们最近扩展了我们的框架以接受“PATCH”请求,这意味着我们现在需要仅在补丁包含要验证的字段时才应用验证。 我
我有一个作为 excel 插件运行的 WPF 应用程序,它有这样的可视化树 精益求精 元素主机 WPF 用户控件 WPF 色带条控件 现在,在 excel 中加载插件时,不会启用位于 WPF 功能区栏
我是一名优秀的程序员,十分优秀!