JWT and one-time tokens?

19,596

Solution 1

Use the user's current password's hash for signing the JWT token, in this way all tokens generated before a successful password change would get invalidated the next time. I got the idea from here https://www.jbspeakr.cc/howto-single-use-jwt/.

Solution 2

Solutions exist, of course.

As with any distributed system (you mentioned scalability) you have to choose between availability and consistence.

  1. You choose availability. In this case you could maintain a list of already-used tokens that you replicate in a eventually consistent manner between all the endpoints. For example when a token is used the respective endpoint send that token to the other endpoints in the backgound. There is however a (short) time frame when that token can be used a second time by another endpoint until that endpoint is updated.

  2. You choose consistency (you won't allow a token to be used multiple times whatsoever). In this case you use a central database with already-used tokens and you check that database everytime you need to perform an action. Scalability? You could use sharding on the token and have n databases, each one being responsible for a tokens subset.

It depends on your business what solution fits best.

Solution 3

Not really no, a JWT token is valid if it hasn't expired and the signature is correct, commonly people will keep a DB of blacklisted tokens which are usually ones where people have logged out etc.

The only sensible way I can think of is give them a short expiry time and maintain a list of tokens that have already been used, you'd then periodically remove the ones that subsequently expire from the DB.

There are actually some DB's that have a TTL on records (dynamoDB, mongodb) so you'd just put the tokens in and set a TTL for when the token expires.

Share:
19,596
Inx51
Author by

Inx51

Updated on June 06, 2022

Comments

  • Inx51
    Inx51 about 2 years

    I'm in the process of rolling my own JWT token auth, however, I would really like it to be a one time-token – so once it's used, the server generates a new token and the client will have to use that token during the next request/call.

    However, it has come to my understanding that JWT is supposed to be 'stateless' – but with the approach of a one time token, I guess I would need to somehow store the valid tokens, since the token will be refreshed once it's used. Or is there any way to avoid storing a value on the server, and still be able to create one-time tokens?

    The two main reasons for why I don't want to store any value is first of all scalability (sure, I could have cache-server inbetween to store the values, but it would be nice if that wasn't required), secondly, JWT is supposed to be stateless from my understanding, which it wouldn't be if I need to store a value on the server to be able to validate the token.

    Any ideas?