0

Ich benutze den HttpInterceptor, um Anfragen mit einem Token erneut zu senden, falls sie eine 401 zurückgeben. Das hatte lange vorher funktioniert, als ich gerade den zwischengespeicherten Token genommen habe. Da das Firebase-Token nicht automatisch aktualisiert wird (mit ForceRefresh), versuche ich jetzt, ein neues Token in Echtzeit in der Interceptor-Klasse zu erhalten. Das Problem besteht darin, dass die Anforderung nicht erneut gesendet wird.Frage Mischen Versprechen mit HttpInterceptor Observables?

Hier ist mein voller Interceptor:

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

Ohne dieses Versprechen Funktion ein neues Token zu erhalten, wird die Anfrage erneut senden wird den letzten mit "next.handle (changedReq);". Ich finde nicht, was ich hier falsch mache. Wird das verursacht, weil ich Versprechungen mit Observablen vermische?

+0

was 'formRequest' Ich denke, es ist' undefined' –

+0

hallo @ RahulSingh, danke für deine Antwort. Ich habe beim Kopieren hier versehentlich eine Zeile entfernt, was formRequest definiert. Es ist der Klon der Anfrage (weil ich dort einen Header hinzufüge). Ich habe den obigen Codeblock aktualisiert. –

+0

Warum verwenden Sie 'return auth.getToken(). Dann (idToken => {' versuchen und entfernen Sie die Rückgabe –

Antwort

0

gelöst durch das Versprechen zu einem beobachtbaren Umwandlung wie von Rahul Singh vorgeschlagen, und mit flatMap, um für die verschachtelte beobachtbaren Rückkehr:

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