Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JWT and one-time tokens?

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?

like image 452
Inx51 Avatar asked May 01 '17 13:05

Inx51


3 Answers

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/.

like image 158
Dhruv Parmar Avatar answered Sep 25 '22 19:09

Dhruv Parmar


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.

like image 27
Constantin Galbenu Avatar answered Sep 22 '22 19:09

Constantin Galbenu


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.

Update 2022 Just to be clear JWT tokens AREN'T stateless they have claims that, as long as they're signed by the right private key - give you a stateful piece of data that can be reissued by your API to reflect the current state of the user.

You'd just need to handle token re-issue on the consumer.

like image 38
Mrk Fldig Avatar answered Sep 21 '22 19:09

Mrk Fldig