每当过期时,我们如何使用HTTP_INTERCEPTORS调用刷新令牌

时间:2019-09-07 07:25:16

标签: angular firebase firebase-authentication

我的目标:在发送请求时,我在标头中传递令牌密钥以验证API请求。如果令牌已过期,我将调用新令牌,然后再次发送带有新令牌的请求以获取响应。

我的错误:我收到以下错误

TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

我的代码:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authToken = localStorage.getItem('id_token')
if(authToken){
  /**
   * Modifying the request to add the token in request header
   */
  const reqClone = request.clone({
    setHeaders: {
      Authorization: authToken
    }
  });
  return next.handle(reqClone).pipe(
    catchError(reason => {
      if(reason.error != undefined && reason.error.code == "TOKEN_EXPIRED"){
        this.reCallWithNewToken(request,reason,next);
      }else{
        return throwError(reason);
      }

    })
  )
}

reCallWithNewToken(request: HttpRequest<any>, error: any ,next: HttpHandler){
this.afAuth.authState.subscribe(user => {
  if (user) {
    user.getIdToken(true)
      .then(token => {
        localStorage.setItem('id_token', token);
        const reqCloneNewToken = request.clone({
          setHeaders: {
            Authorization: token
          }
        });
        console.info("API Request with new token: ", reqCloneNewToken);
        return next.handle(reqCloneNewToken);
      });
    }else{
      return throwError(error);
    }
});
}

1 个答案:

答案 0 :(得分:1)

我能够解决此问题。感谢@JBNizet。 如果有人遇到同样的问题,我会发布我的代码。

我将函数reCallWithNewToken修改为

reCallWithNewToken() {
    return new Observable(observer => {
      this.afAuth.authState.subscribe(user => {
        if (user) {
          user.getIdToken(true)
            .then(token => {
              localStorage.setItem('id_token', token);
              observer.next(token);
            })
            .catch((error) => {
              observer.error(error);
            });
        }
      });
    })
  }

然后进入catchError

if (reason.error != undefined && reason.error.code == "TOKEN_EXPIRED") {
   return this.reCallWithNewToken().pipe(
      switchMap(()=>next.handle(this.addAuthHeader(request)))
   )
}