JWT refresh token strategy
Asked Answered
A

1

6

I see in a blog (here) about Authentication in React with JWT, this setup: access token expiry is 15 minutes , refresh token expiry is 1 month; every 10 minutes the client calls the /refreshToken endpoint, to check if refreshToken is still valid (otherwise the user is shown the login screen).

On the server, the /refreshToken endpoint correctly checks that the refreshtoken is not expired, that the user with the id in refreshtoken payload is still existing and valid (i.e.: the passed refreshToken is present in his refreshTokens array). If everything's fine, a new access token is generated, and sent back with the response.

So far so good. But, before returning the response, a new refreshToken is generated, too, and replaced to the old one into users's refreshTokens array... I think this strategy is flawed, since this way the user will never see his login to expire, even after refresh token (one month in this example) will be overdue...

I did make some tests (lowering the 1 month value to 30 minutes), and effectively the user authorization never expires... Forcing a logout of the user deleting his refreshTokens array obviously works fine, but I'd expect a logout when the refresh token expires by age.

I ask if my understanding is correct (the refreshToken endpoint on the server should not refresh the refresh token, but the access token only), or if I miss something.

UPDATE after @Ghero comment: I see your point... But why to refresh a token if not to update it's expiry?
However, the blog's code used to renew the refresh token:

    const jwt = require("jsonwebtoken");

    exports.getRefreshToken = (user) => {
      const refreshToken = jwt.sign(user, process.env.REFRESH_TOKEN_SECRET, {
        expiresIn: eval(process.env.REFRESH_TOKEN_EXPIRY),
      });
      return refreshToken;
    };

    // REFRESH_TOKEN_EXPIRY is set to 30 days

It looks like it is always postponing the expiry date 30 days in the future. This way it will never expire...

Aric answered 28/1, 2022 at 12:17 Comment(0)
S
8

Having the refresh token being replaced on each use is a current best practice.

Having a one-time use refresh token means that if the refresh token is stolen and used more than once (by you and the hacker), the token service can then detect that and sign-out the user automatically, protecting the user from attacks.

There is a max time that the refresh token is valid, for example 30 days, but that is also often something that you can configure. There are different refresh token lifetime strategies, depending on the service that you use. The picture below shows how IdentityServer deals with refresh tokens: enter image description here

Samalla answered 28/1, 2022 at 13:59 Comment(11)
So the fact the user authentication will never expire (if not forced) is expected? If so, what's the use of REFRESH_TOKEN_EXPIRY ?Aric
see my updated answer.Samalla
Sorry, I don't get it. I am configuring the max time that the refresh token is valid. It is 30 days. Now I set it to 30 minutes, just to for testing purposes. I can confirm that if very time the refresh-token endpoint is called it refreshes the refreshToken, it will NEVER expire... This is what my test confirmed, refreshToken does NOT expire after 30 minutes (and so it will NOT expre after 30 days...), and the user will be logged in FOREVER, if not manually blocked on the server... This not a best practice, I suppose. For sure I'm missing something, but I don't get what it is...Aric
let's say your server is configured for a refresh token expiration of 30 days. The client asks for a new refresh every ten minutes. A new Refresh token is issued, BUT the expiration is not updated (the new refresh token inherits the "original" refresh token expiration). So, after 30 days from the original token's issue the client will be prompted to log in, regardless of how many times a new refresh token was issued)Eustasius
@Ghero: see my updated answer.Aric
I think it all depends and vary between implementations, I have only experience with IdentityServer. In IdentityServer you choose if you want to use a one time refresh token or not.Samalla
But is a NEVER expiring session implementation acceptable?Aric
well, I guess forever is fine too, it all depends on the type of application, if you for example connect Twitter to Instagram, you want that relationship to be forever until you revoke it, so in this case a never expiring refresh token is fine, while if it is just for a site you login to to do some work/business, then you might that user-facing session to be limited.Samalla
Besides the refresh token life time, you also have a separate lifetime of your session cookie. These two items are independent and needs care, so the end users total lifetime is what you expect.Samalla
@Tore Nestenius: I understand now... Thanks! I was limiting my view on public sites which expose a login page to users... Perfect. So, for my use case I will renew the refreshToken, but keeping it's expiry, and everything's fine...Aric
Great! glad I could help you! :-)Samalla

© 2022 - 2024 — McMap. All rights reserved.