• caglararli@hotmail.com
  • 05386281520

Do we really need refresh tokens?

Çağlar Arlı      -    19 Views

Do we really need refresh tokens?

I have read a number of posts of many people expressing their confusion around the extra security gained from using an access token and a refresh token to control access to a resource API. Picking up from this post how-does-a-jwt-refresh-token-improve-security on this site; The author of the question made his case: if an access token can be stolen so can the refresh token, so what's the point of issuing a refresh token? The accepted answer is that unlike an access token, a refresh token can be revoked. If a hacker were to gain access to a long lived access token, there's no way to invalidate the access token(without invalidating access tokens of all users). Therefore, necessitating the use of short lived access tokens and revocable refresh tokens. Use cases for revocable refresh tokens include logging a user out from all sessions, user password change.

While I am convinced that a combination of refresh token and short lived access token makes the authentication/authorization process more secure, I think there is a better way to achieve the same result without the need for a refresh token at all. All we need to do is store the creation date of the access token in the token itself and create a table in the database to store (user id, revocation_timestamp) pair. Whenever we suspect an access token has been compromised, we update the revocation_timestamp to the current time. A hacker with a stolen access token will have access to the resource server for the short lifetime of the access token. When we receive an expired access token, we check in our database for revocation-timestamp corresponding to the user id in the token. If the token was issued later than the time in revocation-timestamp, we issue the user a new access token otherwise they have to supply their credentials. And that is it, the hacker is blocked. No need to store long refresh tokens in our database.

I would love to get feedback on my approach. Do we really need refresh tokens?

ADDITION

Another security feature of refresh tokens is that they can't be used twice. If a malicious user gained access to a refresh token and used it to get a new access token, that new refresh token would be invalidated when the legitimate user tries to use the old refresh token. This too can be achieved with just the access token. We will need to store the timestamp of issuance of latest access token in our DB. Whenever a request for a new access token is made, we compare the timestamp in the provided token with the timestamp of the most recent access token issued. If the timestamp in the provided token doesn't match that stored in our DB, we know this access token is being reused so we stop all active tokens from being able to generate new tokens by setting the revocation-timestamp in our DB to the current time.

The last bit that needs to be addressed is a malicious user continuously supplying the same old compromised token to the server thereby invalidating our legitimate user session repeatedly. In that case, we store another piece of information to capture the most recent date a user supplied their credentials. If the timestamp in the old token is more recent than the last time the user supplied their credentials, we prompt all users to login again when the compromised access token expires. If the last login date of the user is more recent than timestamp in the compromised token, we ignore the threat and keep our user logged in.