【发布时间】:2020-02-06 16:57:14
【问题描述】:
在我的 Angular HttpInterceptor 类中,我正在实现一种刷新机制,用于检测 JWT 令牌何时过期,并从后端检索一个新令牌。一旦检索到新的令牌,它将覆盖本地存储中的令牌,从而延长用户会话的到期时间。
HttpInterceptor 的部分功能是在检测到 JWT 到期日期已到时让用户退出会话。
但是我遇到了一个问题。发出 JWT 请求后,似乎马上又向后端发送了另一个请求。由于此时令牌已过期,API 将返回 403,并且拦截器正在检测到这一点,并在返回带有新 JWT 令牌的响应之前将用户踢出会话。这意味着用户在令牌有机会刷新之前被注销。
通常这不是问题,因为我可以使用 async/await 来确保在发出任何其他请求之前返回新的 JWT。但是,这在拦截器中不起作用,因为它实现了HttpInterceptor 接口,这意味着如果我尝试在接口实现的intercept 方法上使用async 关键字,那么我会得到一个编译器错误作为返回intercept方法的类型必须是Observable<HttpEvent<T>>,不能是Promise<Observable<HttpEvent<T>>>。
//The below violates the HttpInterceptor interface
async intercept(
req: HttpRequest<any>,
next: HttpHandler
): Promise<Observable<HttpEvent<any>>> { ... }
//The below violates the async keyword
async intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> { ... }
我当前的拦截方法代码如下。
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
req = this.addHeaders(req);
if(req.headers.has("refreshTokenRequest")) {
return next.handle(req).pipe(tap(val => console.log("Interceptor handler, req to: " + req.url)));
}
if(localStorage.getItem("jwt_token")) {
if(util.isJwtExpired("jwt_token")) {
console.log("Jwt is expired, getting new token");
this.getNewToken().then(newTokenResponse => { //the .then() method needs to be awaited so that the expired JWT token can be overwritten before ANY other requests are sent
this._authService.setAuthorizationToken(newTokenResponse.token);
console.log("New token set");
return this.handleRequestWithCatchError(req, next);
});
}
}
return this.handleRequestWithCatchError(req, next);
}
因此,我需要一种方法来等待 this.getNewToken() 承诺的返回值,而无需使用 async/await 关键字。有没有办法做到这一点?
【问题讨论】:
标签: javascript angular promise async-await