首页 文章

Angular:仅刷新一次令牌

提问于
浏览
1

我正在使用带有刷新令牌策略的JWT作为身份验证,我在Angular客户端中有一个拦截器,它将令牌作为标头发送 .

我在发送之前检查过期,并在需要时使用我的refreshToken刷新令牌 .

问题是当发送2个(或更多)请求时,都试图刷新令牌 . 我需要一个为刷新令牌发送req的函数,当一次调用多次时,只向服务器提供1个http请求以进行刷新,并将新更新的令牌返回给所有调用它的人 .

这是我的拦截器:

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运营商有关,但我对此有点新鲜 .

1 回答

  • 0

    好吧,我读完之后得到了它:https://www.intertech.com/Blog/angular-4-tutorial-handling-refresh-token-with-new-httpinterceptor/

    我的函数看起来像这样(也处理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));
          });
      }
    }
    

    感谢Vadim(阴道)Siomin的帮助!

相关问题