You should queue your failure requests 401. Since you don't provide the code you use to refresh token I explain to you how you should do it and let you implement it yourself:
- Create a shared retrier for auth requests
- It should has a shared queue of retrying requests. An array [Request] for example
- When a request failure because of the accessToken, it will appended to the requestQueue and wait for the access token to be refreshed.
- So observe the queue and if it was empty and now it has a new item, means that the token recently expired and should perform refresh logic
- Meanwhile another request failed because of the 401 error.
- Add it to requestQueue
- Observer will notice about that BUT it won't try to refresh the token! because it was NOT empty before this request added to it. so it just appended and waits there.
- So after some time, the new access token arrived
- Then you can retry all requests in the queue with the new access token. (From 0 to keep the order or all at once async for more rapid response)
- What if there is a request that already performed but not hit the server unless the queue is empty?
Well, That's very rare condition but it could happen (Already happened for me). if you implement it correctly like I said, and don't mess whit the something like is retrying flag, It will just refresh twice! Not really desired but it's fine and it will work like a charm.
- What if we don't want to refresh it twice or more at that rare condition?
Although it is completely OK with the OAuth 2 rules, but you can do this to prevent the error:
- As soon as you get the 401 error (or any you marked as auth error), remove the access token immediately.
- Any further request will notice there is no access token to request with and they could automatically and directly sent to the requestQueue.
- So there is no more request race condition at all.
- Any note at last?
Don't forget to clear the queue if refresh logic failed. Also you can keep them and retry them if user logged in again, but you have to check the identity of the new logged in user with the previous one who filled the queue.
Hope it helps