0

我正在使用HttpInterceptor重新发送带有令牌的请求,以防它们返回401. 在我刚刚使用缓存的令牌之前,这很有效。由于Firebase标记似乎没有自动刷新(尽管使用forceRefresh),我现在试图在拦截器类中实时获取新标记。问题是现在请求没有被重新发送。问题与HttpInterceptor observables混合的承诺?

这里是我的全部拦截:

export class CustomHttpInterceptor implements HttpInterceptor { 
    constructor(private injector: Injector) { 
    } 

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { 

     const formRequest = req.clone({ headers: req.headers.set('Content-Type', 'application/x-www-form-urlencoded') }); 

     return next.handle(formRequest).map((event: HttpEvent<any>) => { 
      if (event instanceof HttpResponse) { 
       console.log("GOT RESPONSE WITHOUT ERROR. JUST PASSING THROUGH."); 
       return event; 
      } 
     }).catch(err => { 
      console.log("==INTERCEPTOR== CATCH ERROR RESPONSE"); 
      if (err instanceof HttpErrorResponse) { 
       console.log("==INTERCEPTOR== IS HTTP ERROR RESPONSE"); 
       if (err.status === 401) { 
        console.log("==INTERCEPTOR== IS 401"); 
        let postParams = new HttpParams({ fromString: req.body }); 
        if (postParams.has('t')) { 
         //401 while we already provided a token, so a real login is required 
         console.log("==INTERCEPTOR== PROVIDED TOKEN, STILL PROBLEM"); 
         throw new Error("NOT_AUTH"); 
        } else { 
         // most likely session expired, resend token 
         console.log("==INTERCEPTOR== REQUEST WAS WITHOUT TOKEN, RESEND WITH TOKEN"); 
         // get AuthProvider here 
         const auth = this.injector.get(AuthProvider); 
         // token will come in a promise 
         return auth.getToken().then(idToken => { 
          console.log("GOT NEW TOKEN, resending request with token " + idToken); 
          //add token to post params 
          let newPostParams = postParams.append('t', idToken); ====> SUCCESFULLY GOT NEW TOKEN 
          //clone request and add new body 
          const changedReq = formRequest.clone({ 
           method: 'POST', 
           body: newPostParams.toString() 
          }); 
          return next.handle(changedReq); ====> THIS IS NOT PERFORMED 
         }, 
         error => { 
          throw(error); 
         }); 
        } 
       } 
      } else { 
       throw(err); 
      } 
     }) 
    } 
} 

没有这个承诺函数来获取一个新的令牌,该请求被重发使用最后的“next.handle(changedReq);”。我在这里找不到我做错了什么。这是因为我将promise和observables混合在一起吗?

+0

是什么'formRequest'我想这是'undefined' –

+0

喜@ RahulSingh,谢谢你的回复。在这里复制时,我意外地删除了一行,它定义了formRequest。这是请求的克隆(因为我在那里添加了一个头文件)。我更新了上面的代码块。 –

+0

为什么你使用'return auth.getToken()。then(idToken => {'尝试并删除返回 –

回答

0

由承诺转化为可观察到的由拉胡尔·辛格的建议,并使用flatMap为了嵌套观察到的回报解决:

let promise = auth.getToken(); 
let observable = Observable.fromPromise(promise); 
return observable.first().flatMap(idToken => { 
    console.log("GOT NEW TOKEN, resending request with token " + idToken); 

    //add token to post params 
    let newPostParams = postParams.append('t', idToken); 
    //clone request and add new body 
    const changedReq = formRequest.clone({ 
     method: 'POST', 
     body: newPostParams.toString() 
    }); 
    return next.handle(changedReq); 
});