角度:仅刷新令牌一次 [英] Angular: refresh token only once

查看:44
本文介绍了角度:仅刷新令牌一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有刷新令牌策略的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆