0

I understand that the authentication process with access/refresh tokens works like this:

  1. Exchange username/password for refresh_token
  2. Use refresh_token to get access_token
  3. Use access_token for requests (no DB call needed)
  4. If access_token is expired -> use refresh_token to get a new one (DB call needed)

Process to manage/revoke access:

  1. Exchange username/password for refresh_token
  2. Store refresh_token in the DB
  3. Check revoked flag in DB when using a refresh_token to get an access_token
  4. Block by setting revoked flag

DB interactions: Only needed for refreshing tokens. i.e. frequency depends on the access_token lifetime.

User Experience: Login required when

  • first visit
  • refresh_token revoked
  • refresh_token expired

Security implications:

  • refresh_token stolen: vulnerable until manually revoked or for a long time
  • access_token stolen: vulnerable short time. Cannot be revoked
  • logout: access_token remains valid until expired/cannot be revoked

Without refresh_token: +No long lived vulnerability -Bad UX. User needs to login frequently

Now I am wondering why we cannot just use the access_token as the refresh_token:

  1. Exchange username/password for access_token
  2. Store access_token in the DB
  3. Use access_token for all request (no DB call)
  4. When expired: Check DB if revoked flag set. If not -> Create new access_token and set revoked for old token. (optionally, only allow this for x time after expiration. This is the equivalent to an expiration date for the refresh_token)

Now UX/security/DB_call_frequency seem to be identical. So why do we need a seperate refresh_token?

The only argument I can see is that separating them reduces the risk that a refresh_token gets stolen because it is sent less frequently.

Chris
  • 13,100
  • 23
  • 79
  • 162

1 Answers1

0

Create new access_token and set revoked for old token. (optionally, only allow this for x time after expiration. This is the equivalent to an expiration date for the refresh_token)

You wanted to do this again by exchanging username and password?

If so then user needs to login again. You can use Client Credentials Grant https://www.rfc-editor.org/rfc/rfc6749#section-4.4 or Implicit flow https://www.rfc-editor.org/rfc/rfc6749#section-4.2 which sends access token only, these flows doesn't send refresh tokens. If you can send username and password, you can use Client credentials grant and request access tokens every time it gets expired.

Community
  • 1
  • 1
  • No, I did not mean to use username/password. The expired access_token is allowed to be exchanged for a new one unless it has been revoked. So the access_token is basically also the refresh_token – Chris Aug 09 '17 at 14:32
  • How do you get a new access token when old one expires? To get a new one you need to authenticate again. If you don't want to send username and password to get a new token, you need go with refresh token approach. Let me know if I understand you correctly. – Venkatesh Marepalli Aug 09 '17 at 22:24
  • The system should allow to refresh an access_token even after it has expired (optionally with a hard limit of e.g. 1 week). For security, it should check the DB if the token has been blacklisted before refreshing it. So it is basically the same process that is used for refresh_tokens, but it uses the (expired) access_token instead of a separate refresh_token – Chris Aug 10 '17 at 10:15
  • Is this an OAUTH approach? I don't think OAuth has this kind of approach. Which OAuth are you using Google Microsoft? – Venkatesh Marepalli Aug 10 '17 at 17:39
  • No, It's just a JWT token. Not a full oauth workflow – Chris Aug 10 '17 at 19:31
  • If you have it working then you can use this solution. What was your question on this? – Venkatesh Marepalli Aug 10 '17 at 22:08
  • Why most implementations use a separate refresh_token if there is apprently no difference – Chris Aug 11 '17 at 12:26