Reauthentication Processing with RxSwift and Moya

I have a project in which I use Moya with RxSwift extensions. Simple usage examples work fine, I can make queries and get responses in the form of Observables.

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

Then I can subscribe to the observed and print the answer without any problems.

But now I need to handle the authentication logic. The way it works is that I run the above request with a token added as an HTTP header field. Moya allows me to do this transparently using endpointByAddingHTTPHeaderFields in endpointClosure. There are no problems so far.

The problem occurs when the request fails with an HTTP status of 401, which means that I need to re-authenticate by calling another endpoint

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

This returns another Observable, which I can easily map to JSON to get a new token.

I just need to call test () again!

So my question is .... How to add this authentication logic inside the test () function above, so that the Observable returned by test () is already guaranteed to trigger a re-authentication, authentication logic in the event of a failure, and be the result of a second re-authentication request.

I am very new to RXSwift and RX in general, so I don’t know much about the operators that I would use for this.

Thanks!

+5
source share
1 answer
 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 allows catchError to continue observable execution using another observable. The definition we observe here does the following:

  • First, it will request the .auth .
  • Then it reads from the response to get a new authentication token
  • Finally, we recursively call test(with authToken: String) to repeat requests to the test point.
0
source

Source: https://habr.com/ru/post/1237737/


All Articles