Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 我们如何使用HTTP_拦截器在刷新令牌过期时调用它_Angular_Firebase_Firebase Authentication - Fatal编程技术网

Angular 我们如何使用HTTP_拦截器在刷新令牌过期时调用它

Angular 我们如何使用HTTP_拦截器在刷新令牌过期时调用它,angular,firebase,firebase-authentication,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>

我的目标:在发送请求时,我在报头中传递令牌密钥以验证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);
    }
});
}
intercept(请求:HttpRequest,下一步:HttpHandler):可观察{
const authToken=localStorage.getItem('id\u token')
如果(authToken){
/**
*修改请求以在请求标头中添加令牌
*/
const reqClone=request.clone({
集合标题:{
授权:authToken
}
});
返回next.handle(reqClone).pipe(
catchError(原因=>{
if(reason.error!=未定义&&reason.error.code==“令牌已过期”){
这个。重新调用newtoken(请求、原因、下一步);
}否则{
返回投掷者(原因);
}
})
)
}
RecCallWithNewToken(请求:HttpRequest,错误:any,下一步:HttpHandler){
this.afAuth.authState.subscribe(用户=>{
如果(用户){
user.getIdToken(true)
。然后(令牌=>{
setItem('id_token',token);
const reqCloneNewToken=request.clone({
集合标题:{
授权:令牌
}
});
console.info(“带有新令牌的API请求:”,reqCloneNewToken);
返回next.handle(reqCloneNewToken);
});
}否则{
返回投掷器(错误);
}
});
}

我能够解决这个问题。多亏了@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)))
   )
}

传递给catchError()的回调应该返回一个可观察的。但是它没有。它只调用
this.reCallWithNewToken(请求,原因,下一步);
。即使添加了
return
,它仍然不会返回任何内容,因为
reCallWithNewToken()
不返回可观测值,而是订阅可观测值。