2015-12-09 10 views
5

Ho un progetto in cui sto utilizzando Moya con estensioni RxSwift. I casi di utilizzo semplice funzionano bene, sono in grado di fare richieste e ottenere risposte sotto forma di Osservabili.Gestione della ri-autenticazione con RxSwift e Moya

public func test() -> Observable<Response> { 
    return provider 
    .request(.test) 
    .retry(5) 
} 

Posso quindi sottoscrivere l'osservabile e stampare la risposta senza problemi.

Ma ora ho bisogno di gestire la logica di autenticazione. Il modo in cui funziona è che eseguo la richiesta di cui sopra con un token aggiunto come HTTP Header Field. Moya me lo consente in modo trasparente utilizzando endpointByAddingHTTPHeaderFields in endpointClosure. Nessun problema finora.

il problema sorge quando la richiesta non riesce con stato HTTP 401, che significa che ho bisogno di ri-autenticarsi chiamando un altro endpoint

provider.request(.auth(user, pass)).retry(5) 

Ciò restituisce un altro osservabile che posso facilmente mappare JSON per ottenere il nuovo gettone.

Quindi devo solo chiamare test() di nuovo!

Quindi la mia domanda è ... Come posso aggiungere questa logica di autenticazione all'interno del test () funzione di cui sopra, in modo che il Observable restituito dal test() è già garantito di aver eseguito la ri- logica di autenticazione in caso di errore ed essere il risultato di una seconda richiesta re-autenticata.

Sono molto nuovo a RXSwift e RX in generale, quindi sono un po 'all'oscuro degli operatori che utilizzerei per farlo.

Grazie!

+0

Hai mai risolto questo? – tskulbru

+0

Il 401 viene visualizzato come errore o è un oggetto di risposta valido? –

+0

Se il primo, questa risposta potrebbe aiutarti: http://stackoverflow.com/questions/35841054/rxswift-user-input-on-error-and-continuation/38341690#38341690 –

risposta

0
public func test(with authToken: String) -> Observable<Response> { 
    return provider 
     .request(.test) 
     .endpointByAddingHTTPHeaderFields(["Authorization": authToken]) 
     .catchError { error in 
     if needsReauth(error) { 
      return provider.request(.auth(user, pass)).map { parseToken($0) } 
      .flatMap { token in 
       return test(with: token) 
      } 
     } else { 
      return .error(error) 
     } 
     } 
} 

catchError permette di continuare l'esecuzione del osservabile utilizzando un altro osservabile. L'osservabile che definiamo qui è il seguente:

  1. Innanzitutto, richiede l'endpoint.
  2. Quindi legge dalla risposta per ottenere il nuovo token di autenticazione
  3. Infine, chiamiamo in modo ricorsivo test(with authToken: String) per riprovare a eseguire query sull'enpoint di test.
Problemi correlati