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); 
});