Retrofit Authenticator Refresh Token - android

I’m looking for a similar solution that can handle multiple requests that occur in parallel. Wouldn’t this solution refresh a token for each request that received 401 ? So if for instance, I enter a screen and issue 5 different requests, each one will receive a 401 and each one will issue a refresh token request in that runBlocking block. Is there an elegant way of stopping 4 out of the 5 requests and return to them with the result of the refresh that occurred in the first request?

Related

Use RxJava in queue-like manner and pause/start queue

I'm trying to use RxJava in my Android application, along with Retrofit, to interact with a RESTful API.
In my Android app I sent out a number of requests at various UX events. If one of the request returns an 'Invalid Token' error, I want to pause any other requests that get queued before they start so that I can renew the user's token, and then resume the paused requests.
Is this possible using RxJava? I'm just learning the library and am having trouble finding this functionality.
Thanks,
If these requests are sent in parallel, then you will likely get multiple "Invalid Token" errors. You would want to refresh the token for only the first instance of the error. To pause requests while the token is being refreshed, think about the source of the valid token being an observable.
Let's assume you have a network handling class that has methods:
Single<Response> makeNetworkRequest(Request request) { ... }
Single<Boolean> getToken() { ... }
It is implemented such that a value is emitted when a token is available, but otherwise waits until the token is refreshed.
Then, your observer chain will look something like:
observerChain
.flatMapSingle(request -> networkHandler.makeNetworkRequest(request)
.retryWhen(error -> error.flatMapSingle(e -> networkHandler.getToken()))
...
The retryWhen() operator recovers from the error by providing an observable that, when non-empty, will resubscribe to the upstream observable, in this case, the makeNetworkRequest().
Since you don't show any of your code that you are trying to adapt, you will have to make adjustments to the code above to get it to work with your application.

Need to call an api to refresh token in android mvvm using retrofit ,where to write the logic?

At the time of login we get a authorization token and a refresh token,authorization token is attached with all API in header ,but after some time authorization token will expire and we will get 401,to refresh we need to call a API with refresh token that we get at the time of login in response we will get a new authorization token and refresh token,problem is where to catch 401 and write at one point to call refresh token API and resend the previous failed API ,we cant call API in interceptor.
Check this Refresh Access Token globally (Separate logic as a module) using RxJava 2, RxAndroid 2 and Retrofit 2 post.
Maybe it will help you
Okhttp (which acts as the http layer of retrofit) has a mechanism for doing just this. Have a look at https://square.github.io/okhttp/4.x/okhttp/okhttp3/-authenticator/
You provide the Authenticator to your Okhttp builder during setup and this then responds to 401 error responses to fetch a refresh token.

Catching 401 and refreshing Firebase Id Token

My app uses Firebase to authenticate users by phone number, a migration from Digits.
I add the idToken from Firebase to my calls.
I listen with an interceptor on my httpclient if a 401 was trown, if so, I logged out.
I noticed after one hour the 401 came in, so I added an addIdTokenListener in my App class. When it changes I update my token to sign my calls.
It worked, but not flawless, sometimes a 401 was thrown and I still logged the user out...
I am writing something in my interceptor to get the IdToken from the user, but the call firebaseUser.getIdToken() is async. So I'm starting to make things complicated, I guess.
Could anyone point me in the right direction? What is your workflow?
You're going in the right direction. One thing you may want to do is alter your logic a little based on the reason for the ID token validation failure. You can unpack the ID token data yourself and check the expiration field. If the token has expired, return a different code that triggers the retrieval process, before trying the call again.

okhttp: how to handle unrequested/unexpected 100 (continue) response from server?

TLDR: Is there a way to force OkHttp to correctly handle unexpected/unrequested 100 Continue HTTP responses?
I'm using OkHttp 3.8.1 on Android to POST to a poorly-behaved server.
Even though the request does not include an "Expect: 100-continue" header, the web server returns a 100 Continue response. Rather than continuing to send the request body, then getting the actual (200) response, OkHttp stops there and sends back the 100 Continue response in my okhttp.Callback.
I tried explicitly including "Expect: 100-continue" in the request to trigger OkHttp's logic, but the server (possibly due to some bug) claims the header is malformed and rejects the request. I also tried sending "Expect:" (no value), but the server still sends the 100 Continue response and OkHttp stops there.
Other HTTP clients (I've tested 3 so far) can talk to that server just fine. They handle the 100 Continue response correctly even though they didn't see "Expect: 100-continue" in the request header. Is there an option I can set, or an interceptor I can write, to make OkHttp do the same?
Sounds like something we can fix in OkHttp. This is weird and the server is broken, but if other clients handle it OkHttp should too.
Please report a bug there?

What is the best way to add and check authorization token?

I am implementing an android application which will validate user details against the server and stores the return token. For subsequent requests it should send the token along with each request. Here are some of the points I need to consider.
I am using Retrofit 2 library to send http requests to the server
The token will be generated by JWT library and sent back to the client
If the token is not present or invalid or expired, the server will throw 400/401 error
Design
The landing page of android app is not login protected so that user can see the app before using his credentials
Once he is on MainActivity, any requests to other screens require authentication. So all other activities will check for token and redirect to login activity.
In case any response received from server has 400/401 header, it should also redirect to login page.
Considering the above requirements, I tried to add an interceptor in Retrofit service generator class which which will be executed on every request/response.
Problem
The interceptor is executed for every request not just once per activity. i.e. it is opening n number of logic activities if there are n number of async calls in the main activity (because no token will be present for all those requests).
Can someone help me in identify:
If there is a better design that can avoid such problem or
Is there any way to suspend main activity until login is completed and then resume it.

Categories

Resources