对于多个过期的访问令牌,ngx-restangular刷新令牌一次

时间:2018-04-03 21:48:13

标签: angular rest oauth-2.0

我正在使用Angular 5和ngx-restangular。 我想在令牌过期时发送刷新令牌。我用了the code provided by the library。只发送一个请求时它工作正常!请求收到错误,然后发送刷新令牌请求,然后使用新的访问令牌重新发送请求。

但是当我同时有两个请求时,它们都会出错并且都发送刷新令牌请求。第一个获取新的访问令牌,但第二个获取错误,因为它发送旧的刷新令牌。

解决方案是什么?是服务器还是客户端?

1 个答案:

答案 0 :(得分:0)

我针对此问题的解决方案是创建一个refreshedToken待处理的请求数组。因此,当我收到401错误(访问令牌已过期)时,我请求一个新令牌,同时也创建一个flag = true。尽管此flagtrue,但我将请求添加到了数组中。解决了新令牌后,我将令牌替换为数组中的请求,然后重复它们。

这是我的代码:

app.module.ts

RestangularProvider.addErrorInterceptor((response, subject, responseHandler) => {
  if (response.status === 401) {
    if (AuthService.refreshingToken) {
      // refreshTokenRequest is already sent and we should wait. So we add the request to the pending array
      AuthService.requestsPendingRefreshToken.push({ response, subject, responseHandler });
    } else {
      refreshAccesstoken()
        .pipe(
          switchMap(refreshAccesstokenResponse => {
            const newHeaders = new HttpHeaders({ Authorization: 'Bearer ' + refreshAccesstokenResponse });
            const newReq = response.request.clone({ headers: newHeaders });
            return response.repeatRequest(newReq);
          })
        )
        .subscribe(res => responseHandler(res), err => subject.error(err));
    }
    return false; // error handled
  }
  return true; // error not handled
});

auth.service.ts

refreshAccesstoken() {
  return this._http.get(url, requestOptions).pipe(
    map(accessToken => {
      this.repeatPendingRequests();
      this.refreshingToken = false;
      return accessToken;
    })
  );
}
repeatPendingRequests() {
  this.requestsPendingRefreshToken.forEach(pr => {
    const { response, subject, responseHandler } = pr;
    const newHeaders = new HttpHeaders({ Authorization: 'Bearer ' + this.accessToken });
    const newReq = response.request.clone({ headers: newHeaders });
    response.repeatRequest(newReq).subscribe(res => responseHandler(res), err => subject.error(err));
  });
  this.requestsPendingRefreshToken = [];
}