2016-04-28 17 views
8

Sono nuovo di Angular2 e cercando cattura 401 di errore per token di aggiornamento con il piano per riprovare richiesta originale ...Angular2: Catching 401 errori per token di aggiornamento

Ecco il mio metodo authService.refresh:

refresh() : Observable<any> { 
    console.log("refreshing token"); 
    this.accessToken = null; 
    let params : string = 'refresh_token=' + this.refreshToken + '&grant_type=refresh_token'; 
    let headers = new Headers(); 
    headers.append('Authorization', 'Basic ' + this.clientCredentials); 
    headers.append('Content-Type', 'application/x-www-form-urlencoded'); 

    return Observable.create(
     observer => { 
      this._http.post('http://localhost:8080/oauth/token', params, { 
        headers : headers 
      }) 
      .map(res => res.json()).subscribe(
       (data) => { 
        this.accessToken = data.access_token; 
        observer.next(this.accessToken); 
        observer.complete(); 
       }, 
       (error) => { 
        Observable.throw(error); 
       } 
      ); 
     }); 
} 

e poi si tenta di utilizzare la funzionalità di aggiornamento nel mio metodo di componente:

update(index : number) { 
let headers = new Headers(); 
headers.append('Authorization', 'Bearer ' + this._authService.accessToken); 
this._http.get('http://localhost:8080/rest/resource', { 
    headers : headers 
}) 
.catch(initialError =>{ 
    if (initialError && initialError.status === 401) { 
     this._authService.refresh().flatMap((data) => { 
     if (this._authService.accessToken != null) { 
      // retry with new token 
      headers = new Headers(); 
      headers.append('Authorization', 'Bearer ' + this._authService.accessToken); 
      return this._http.get('http://localhost:8080/rest/resource', { headers : headers }); 
     } else { 
     return Observable.throw(initialError); 
     } 
     }); 
    } else { 
     return Observable.throw(initialError); 
    } 
}) 
.map(res => res.json()) 
.subscribe(
    data => { 
     this.resources[index] = data; 
    }, 
    error => { 
     console.log("error="+JSON.stringify(error)); 
    } 
); 
} 

Questo non funziona per qualche motivo ... mi chiedo quale sia la corretta implem introduzione della funzionalità di aggiornamento dei token in angular2? enter code here

risposta

2

Non v'è alcuna necessità di utilizzare Observable.create(

 return this._http.post('http://localhost:8080/oauth/token', params, { 
       headers : headers 
     }) 
     .map(res => res.json()) 
     .map(data => { 
       this.accessToken = data.access_token; 
       observer.next(this.accessToken); 
       observer.complete(); 
      }, 
     ).catch(error) => Observable.throw(error)); 

semplicemente non chiamare .subscribe() (che restituirà un Subscription invece di un Observable, invece usare .map(...) e .catch(...)

+0

Ci scusiamo per il DV, il mio male, il pensiero parlavi la seconda parte del PO di codice. – paulpdaniels

+0

Nessun prob. Grazie per il commento. –

4

Oltre al Günter del rispondere, vorrei sfruttare il accessToken dal parametro di callback flatMap invece di utilizzare una proprietà del servizio:

if (initialError && initialError.status === 401) { 
    this._authService.refresh().flatMap((accessToken) => { 
    // retry with new token 
    headers = new Headers(); 
    headers.append('Authorization', 'Bearer ' + accessToken); 
    return this._http.get('http://localhost:8080/rest/resource', { 
     headers : headers }); 
    }); 
} else { 
    return Observable.throw(initialError); 
} 

Questo articolo potrebbe interessarti (sezione "Gestione della sicurezza"):

+0

Che dire di più 401 simultanei quando il token è scaduto. Sembrerebbe che la tua soluzione chiamerebbe più volte per aggiornare(), prima riuscendo e il resto fallendo. Forse condividere la promessa di aggiornamento iniziale per il resto delle richieste potrebbe risolvere questo problema. – user1740331