2

I'm implementing my JWT method by using the double submit method: where we separate the payload & header portion of the JWT from the signature.

The header & payload is stored in a separate cookie, not HttpOnly so its accessible by the client, and the signature is HttpOnly.

The implementation seems pretty straight forward, but I'm having an issue understanding how refresh works.

For example, since I'm using firebase, the users jwt token has an expiration of 1 hour. When that expires, we need to automatically refresh the token, but this means we are refreshing the whole token. The whole point of the signature token is to be session long.

How can we refresh just the payload & header part of the token, without it affecting the signature?

The strategy I am using is based on this article: https://medium.com/lightrail/getting-token-authentication-right-in-a-stateless-single-page-application-57d0c6474e3

alex067
  • 335
  • 3
  • 7

1 Answers1

1

What you are trying to accomplish does not work based on the JWT specification. Let's focus on the relevant part (taken from JWT.io), the scope of the signature:

To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

You sign the header and the payload. According to RFC 7519, the payload contains the "exp" claim, which defines the expiration time.

This means, if you want to refresh the token, you have to change the expiration time. This changes a value that is signed. Therefore, the signature must also change, otherwise it doesn't validate the rest of the token.

Long story short, you cannot change the expiration time without changing the signature

EDIT: Based on the source of this method, one crucial information was missing in the original question.

My answer above is still correct, if you implement JWT expiration with the "exp" claim. The linked method sets the "exp" to a full day (see chapter "Other Important JWT Payload Content"), thereby avoiding an actual token timeout. When the token (containing header and payload) gets refreshed, they do not change the content at all, but they only change the expiration date of the cookie. That way, the token stays the same and the signature stays valid.

So your issue is setting the "exp" claim to 1 hour instead of 1 day as suggested in the article.

Demento
  • 7,249
  • 5
  • 36
  • 45
  • I came across the method here: https://medium.com/lightrail/getting-token-authentication-right-in-a-stateless-single-page-application-57d0c6474e3 How are they able to implement this technique? – alex067 Mar 05 '20 at 20:03
  • @alex067 - Oh, I see what they did there! They implemented the expiration based on the cookie lifetime and not on the "exp" claim in the JWT token. It would be a good idea to link this article in the question itself for better understanding. I will update my answer based on that knowledge. – Demento Mar 05 '20 at 20:26
  • So okay so basically they are not actually refreshing the token, but just refreshing the set expiration time of the token right? – alex067 Mar 05 '20 at 20:35
  • @alex067 - Yes, exactly. That's how I understood the article. In the chapter "The Cookie Split" they say, that they set the cookie attribute "30 minute expiry" for cookie 1. So with every request, they set the same cookie with the same content again, just resetting the 30 minute period. – Demento Mar 05 '20 at 20:39
  • Ah thanks so much for clearing that up! that makes sense to me now – alex067 Mar 05 '20 at 20:43
  • 1
    @alex067 you should now that this is a terrible idea. If you ignore the expiration in the token and instead rely on the expiration of the cookie, then you are making a permanent JWT. This is because a JWT (usually) cannot be revoked, which is why it has a short lifetime. If it also cannot expire then it lives forever and whoever steals it gets permanent access as the end user. Of course the actual user will lose access when the cookie expires, but if an attacker steals it, it no longer lives in a cookie and so will never expire. – Conor Mancone Aug 02 '20 at 21:26
  • 1
    As a result there is very little point in this whole "set cookie expiration for an hour and then reset it for longer as needed". This *completely* breaks the main security controls in a JWT. – Conor Mancone Aug 02 '20 at 21:28
  • 1
    Therefore this answer is completely correct: what you are trying to do simply is not possible in the JWT specification. – Conor Mancone Aug 02 '20 at 21:29