2017-10-20 16 views
1

J'essaye d'écrire mon premier code pour attraper des erreurs 401 en utilisant HttpInterceptor. Ce que je veux faire est en fonction d'une condition créer un nouveau jeton d'authentification, puis réessayer avec cela. Mais actuellement, mon code fait la tentative, mais il le fait avant que le nouveau jeton d'authentification ait été créé. Voici mon code:HttpInterceptor réessayer dans Angular 4.3

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

    return next.handle(request).catch(error => { 

     if (error.status === 401) { 

      console.log('401 error'); 

      //check for valid refresh token 
      let refreshToken = localStorage.getItem('refresh_token'); 

      this._refreshTokenService.getRefreshToken(refreshToken).subscribe(
       refreshToken => { 
        if (refreshToken != null) { 

         console.log('valid refresh token') 

         //if valid refresh token, relogin and create new auth token 
         console.log(localStorage.getItem('auth_token')); 

         this._userService.logout(); 

         let email = localStorage.getItem('profile_email'); 

         this._userService.autoLogin(email) 
          .subscribe(
          result => { 
           if (result) { 
            console.log('new auth token created'); 

            let auth_token = localStorage.getItem('auth_token'); 

            //retry 
            request = request.clone({ headers: request.headers.set('Authorization', `Bearer ${auth_token}`) }); 
           } 
          }); 


        } 
        else { 
         console.log('invalid refresh token'); 
        } 
       }); 
      return next.handle(request); 
     } 
     else { 
      console.log(error.status); 
     } 
    }); 
} 

Je suis toujours se familiariser avec la syntaxe Tapuscrit, je pense que je dois faire la nouvelle tentative se produire seulement après que le nouveau jeton a été créé, mais je ne suis pas sûr de la syntaxe exacte dans ce Cas. Toute aide serait très appréciée!

Répondre

1

Désolé je ne peux pas répondre dans les commentaires. Je suppose que tout cela concerne le chaînage Observable.

Fondamentalement, tout ce que vous appelez avant votre dernier return next.handle(request); est traité avant d'effectuer votre appel http. Sauf que tout à l'intérieur this._refreshTokenService.getRefreshToken(refreshToken).subsribe() sera traité de manière asynchrone.

Vous devriez enchaîner votre Observable comme ceci:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<any> { 
    return next.handle(request).catch(error => { 
     return this._refreshTokenService.getRefreshToken(refreshToken).subscribe(
      refreshToken => { 
       return next.handle(request); 
      } 
     ); 
    }); 
} 
+0

Salut, merci pour votre réponse. J'ai essayé de déplacer la ligne 'return next.handle (request)' pour qu'elle soit directement après la ligne clone, mais cela me donne l'erreur de syntaxe 'Type void n'est pas assignable au type ObservableInput '. Je suppose que je dois avoir la ligne de retour où je l'ai dans mon post original, mais comment puis-je l'empêcher d'être exécuté avant que le reste du code a fini de fonctionner? – user517406

+0

Aussi, j'ai essayé votre exemple et il donne erreur 'Type Abonnement n'est pas assignable à type ObservableInput '. Ce n'est probablement pas si difficile à résoudre, mais la syntaxe est difficile à comprendre :) – user517406