Should I store JWT tokens in redis?

manish keer picture manish keer · Jul 3, 2017 · Viewed 19.6k times · Source

I'm building an application with ExpressJS, Mongodb(Mogoose). Application contains routes where user has to be authenticated before accessing it.

Currently I have written a express middleware to do the same. Here with the help of JWT token I'm making mongodb query to check whether user is authenticated or not. but feel this might put unnecessary request load on my database.

should I integrate redis for this specific task?
does it will improve API performance? or should go ahead with existing mongodb approach?

would be helpful if I get more insights on this.

Answer

Michael Ekoka picture Michael Ekoka · Sep 23, 2017

TLDR: If you want the capability to revoke the token at some point, yes, store it in something fast like Redis.

One of the well documented drawbacks of using JWT is that there's no simple way to revoke a token if for example a user needs to be logged out or the token has been compromised. Revoking a token would mean to look it up in some storage and then deciding what to do next. Since one of the points of JWT is to avoid round trips to the db, a good compromise would be to store it in something less taxing than an rdbms. That's a perfect job for Redis.

As suggested in the comments a good approach is to make the list a blacklist (i.e. a list of invalidated tokens). Upon each request you lookup the list to ensure the token is not present in it. You can further improve on memory space and performance during the lookup step by using a probabilistic algorithm to store the token. A simple implementation is to not store the entire token in the redis blacklist. Just store the first few characters of the token. You can then store a fuller version of the blacklist using a more persistent solution (filesystem, rdbms, etc). This is an optimistic lookup that will still quickly tell you that a token is not present in the blacklist (which would be the more common case). If a token being looked up happens to match an item in the redis blacklist (because its first few characters match), then move to an extra lookup on the persistent store. Another more efficient and relatively simple to implement algorithm for this is something called a Bloom filter.