I'm having some issue with an access token not being refreshed in my mobile application. I'm trying to figure out what would be the best approach to fix it.
This is the scenario faced by some mobile app users:
- A user logs in the app through the authorization code flow (webview of Identity Service)
- The app exchanges the authorization code with an access + refresh tokens and stores the refresh token in the keychain for next time.
- Next time, the user logs in to the app using a passcode.
- The refresh token is sent to the Identity Service in exchange for an access token
- The new access + refresh token is sent back to the app
- The app never receives the tokens for some unexpected reason (network switched, lost internet etc. )
- The app retries and sends the same refresh token again
- The Identity Service refuses it because it’s been used already even though it never reached the app
Because the refresh token is single use only in our Identity Service configuration the user needs to go through the authorization flow again and needs to enter their username/password which is a quite annoying user experience.
In terms of security, a reusable refresh token could be an issue as well. If someone finds a way to steal it, a hacker would be able to login without the user being aware of it.
So I'm kind of in a deadlock and I'm wondering what's the best approach to get the best security and also allow the user to reuse a refresh token in case the network dropped.
Few possibilities I thought of would be to:
- Expire the refresh token not immediately but after X minutes to allow reusing it.
- Emit a new refresh token but still accept older refresh token (up to X refresh tokens)
What's the right approach in term of security?