角度:仅刷新令牌一次 [英] Angular: refresh token only once
问题描述
我正在使用带有刷新令牌策略的JWT作为身份验证,并且在Angular客户端中有一个拦截器,该拦截器将令牌作为标头发送.
I'm using JWT with refresh token strategy as authentication and I have an interceptor in my Angular client that sends the token as a header.
我在发送前检查是否已过期,并在需要时用我的refreshToken刷新令牌.
I check for expiration before sending, and refresh the token with my refreshToken if needed.
问题在于,当发送2个(或更多)请求时,两个请求都试图刷新令牌.我需要一个函数来发送req以获得刷新令牌,并且一次调用多次,仅使1个http req到服务器进行刷新,并将新的更新令牌返回给所有调用它的人.
The problem is when sending 2 (or more) requests, both trying to refresh the token. I need a function that sends req for refresh token and when called multiple times at once, makes only 1 http req to the server for refresh and returns the new updated token to all who called it.
这是我的拦截器:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authService = this.inj.get(AuthService);
const token = authService.getToken();
// if no token or this is a refresh token req
if (!token || req.url.split('/').pop() === 'refreshToken') {
return next.handle(req);
}
const decoded = jwt.decode(token);
// if token expired
if (decoded.exp < (Date.now() / 1000)) {
return authService.refreshJWTToken().concatMap((newToken) => {
const clonedReq = req.clone({
headers: req.headers.set('Authorization', 'JWT ' + newToken)
});
return next.handle(clonedReq);
});
}
const clonedReq = req.clone({ headers: req.headers.append('Authorization', 'JWT ' + token) });
return next.handle(clonedReq);
}
我需要的功能是 authService.refreshJWTToken();
我知道这与Observables运算符有关,但我对此有些陌生.
I know it's something that has to do with Observables operators but I'm a bit new to this.
推荐答案
好吧,我在阅读以下内容后明白了这一点: https://www.intertech.com/Blog/angular-4-tutorial-handling-refresh-token-with-new-httpinterceptor/
Alright I got it after reading this: https://www.intertech.com/Blog/angular-4-tutorial-handling-refresh-token-with-new-httpinterceptor/
我的函数如下所示(也处理请求):
My function looks like this (also handling the req):
handleRefreshToken(req: HttpRequest<any>, next: HttpHandler): Observable<any> {
const authService = this.inj.get(AuthService);
if (!this.isRefreshingToken) {
this.isRefreshingToken = true;
// Reset here so that the following requests wait until the token
// comes back from the refreshToken call.
authService.tokenSubject.next(null);
return authService.doRefreshToken()
.switchMap((newToken: string) => {
authService.tokenSubject.next(newToken);
return next.handle(this.addToken(req, newToken));
})
.catch(err => {
authService.logout();
return Observable.throw(err);
})
.finally(() => {
this.isRefreshingToken = false;
});
} else {
return authService.tokenSubject
.filter(token => token != null)
.take(1)
.switchMap(token => {
return next.handle(this.addToken(req, token));
});
}
}
感谢瓦迪姆(Sadin)的帮助!
Thanks to Vadim (the vagin) Siomin for the help!
这篇关于角度:仅刷新令牌一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!