JsonWebToken: activity-based expiration vs issuing time-based expiration
Asked Answered
A

2

6

I'm fairly new to token based authorization. I'm trying to find the flaws in a custom expiration/token-refresh scheme.

I have a basic JWT auth setup in an Express API; I'm setting the JWT expiration to 1 hr; However, JWT checks token expiration relative to the time the token was issued. I would prefer that the expiration time gets reset after each successful api call. If my user is actively using the app for more than an hour, I don't want them to have to log back in to refresh the token (and possibly lose whatever data they are working on.)

On the the other hand, I do want the token to expire if they are not responsive for more than an hour.

I have come up with the following approach:

During every successful API request, issue a new JWT and send it in a custom response header. My client side code is responsible for checking this JWT response header and using its value as the new default Authorization request header. Thus, if there is no API request from the user for more than 1 hour, the token will expire and not be refreshed. Login would then be required. In addition, the original issue-date of the token (timestamp of login-authentication) will be stored so that a "hard-expiration" of the token will be enforced after 24 hours.

This seems fairly straightforward and reasonably secure, but I haven't seen any reference to it in my JWT research. Is there a better way to achieve the same goal? Am I missing a major security hole with this approach?

UPDATE: After thinking of this for some time, I realized that the problem with this is that it opens the door to replay attacks that could not be thwarted by token expiration. So there should absolutely be a "hard-expiration" check: hard expiration would invalidate the token at some time after issue date, regardless of recent user activity.

Aindrea answered 10/12, 2014 at 18:58 Comment(2)
Do you issue a new token based on the validity of the old token? Other then your client code becoming a bit awkward, I don't see major security concerns. Obviously, issuing a new token is not free, so you'll pay a performance penalty when calling your API. Also, you won't be able to separate the issuing code from the API code. OAuth 2.0 uses refresh tokens to renew the issued access token once it expires.Miscellanea
@user18044 - yes, I would issue the new token based on the validity of(and data contained within) the old tokenAindrea
P
3

Here you can check my answer for this scenario: implementing refresh-tokens with angular and express-jwt

What I have done is to have a time window where the server checks if the token expiration and the local server time is in this window and then send a response header with the refreshed token.

Premiere answered 17/12, 2014 at 18:29 Comment(0)
C
0

If you agree and realize that you need a hard expiry time anyhow, why not set the expiry time of the (one and only) access token to that and stick to plain OAuth 2.0? An asymptote of what you're doing now, would be to issue your own API specific token/cookie after first use of the access token (in the API response) and enforce subsequent API access based on that. That is a valid approach, but duplicates a lot of stock OAuth 2.0 Authorization Server functionality in your own API. I don't see a good reason to go there.

Consulate answered 12/1, 2015 at 23:24 Comment(6)
This approach would allow me to have a token invalidated after a very short period, but only if the user becomes inactive. For example, if the user is on a public computer and said user walks away without logging out, you could have the token expire 30 minutes after the last API call. I wouldn't want to set the hard expiration so short, because the user would have to login every 30 minutes regardless of their activity. Annoying, and could lead to data loss (say they were filling and submitting a very long form).Aindrea
you're mixing token expiry with user login expiry; they're not the sameConsulate
Ok, I'm ok with not being an expert on this. Perhaps you can explain how I can achieve my said goal by separating these concerns? Or you could point me to a resource?Aindrea
the login session exists on the Authorization Server; the expiry of the token that the client uses is relatively independent of that; whenever the client's token expires, it will consult the Authorization Server for a new one; if the user can authenticate successfully or if the login session still exists (which is what you're looking for), a new token is issuedConsulate
Ok, thank you, I believe I understand the pattern. I guess I see the requirement of a session as a downside - that's what makes JWT attractive to me in the first place.Aindrea
If you'd want to synchronize sessions between client and Authorization Server you could use OpenID Connect with its (not-yet-fully-standardized) Session Management extension; it would issue a "passive" authorization request on a regular basis that would refresh the ID token. See openid.net/specs/openid-connect-session-1_0.htmlConsulate

© 2022 - 2024 — McMap. All rights reserved.