Ronny
Ronny

Reputation: 21

Doorkeeper refresh token and concurrency

In the current implementation of doorkeeper, When the access_token is refreshed doorkeeper also sends a new refresh_token.This is a valid implementation but it becomes problematic when there are concurrent apis calls from my client side (ios, android) calling to refresh the access token at the same time. This means that there will be at least 1 thread ending up with expired tokens that it cant refresh.

Anyone has solution for this race condition?

Upvotes: 1

Views: 1756

Answers (1)

phindmarsh
phindmarsh

Reputation: 879

We've solved this before (not with doorkeeper) a couple of different ways.

Request Queue:

On our mobile apps we've implemented a request queue, and just before a request is made we check if the token needs to be refreshed then we pause the queue, refresh the token, then unpause again. No changes to the server required in this case

This has tradeoffs (you need to sync your request threads etc), but is pretty reliable at stopping the refresh contention without needing to modify the server.

Refresh jitter and JWT:

Since we are using JWT (where the access_token expiry is written into the token and not revoked at the server end), you can add a random number of "jitter seconds" to the refresh expiry each time you check. This decreases the likelihood of two requests trying to refresh at the same time. I used this in an AngularJS app that would get all confused with several tabs open. There was a random chance one tab would refresh before the rest, while the rest could continue to use their existing access_token until the new one was returned and updated.

This would probably also work without JWT if you can manage to get your access_tokens to stay valid when their corresponding refresh token is used, which would allow the 'other' requests to continue to use their 'old' token until the next time.

It's not entirely foolproof, but reduced the likelihood enough we were happy with it.

Expiry buffers for tokens:

The last way was when a refresh was executed, don't actually expire the token for another few seconds later so any 'concurrent' threads just get the new token returned. This was easy enough when I'd written the server component from scratch, but might not be so easy with doorkeeper. I think you'd get more milage from the other two approaches.

Upvotes: 2

Related Questions