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.
To keep them secure, you should always store JWTs inside an httpOnly cookie. This is a special kind of cookie that's only sent in HTTP requests to the server. It's never accessible (both for reading or writing) from JavaScript running in the browser.
A JWT needs to be stored in a safe place inside the user's browser. Any way,you shouldn't store a JWT in local storage (or session storage). If you store it in a LocalStorage/SessionStorage then it can be easily grabbed by an XSS attack.
The safest place: Browser's MemoryBrowser's memory like states is definitely the safest place to save. However, the application couldn't persist the JWT if the user refresh the browser. So we still have to consider to store JWT to the cookie or the localStorage.
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 look up 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 approach is to have layered lookups. For instance, you could have a small in-app store that only tracks the first few (e.g 1 to 4) bytes of your blacklisted tokens. Then the redis cache would track a slightly more complete version of the same tokens (e.g. first 2 to 8 bytes). You can then store a full version of the blacklisted tokens using a more persistent solution (filesystem, rdbms, etc). This is an optimistic lookup strategy that will quickly confirm that a token is absent from the blacklist (which would be the more common case). If a token being looked up happens to match an item in the in-app blacklist (because its first few bytes match), then move on to an extra lookup on the redis store, then the persistent store if need be. Some (or all) of the stores may be implemented as tries or hash tables. Another efficient and relatively simple to implement data structure to consider is something called a Bloom filter.
Obviously, you'd have to adapt the above approach if you routinely blacklist millions of long-lasting tokens (which may also indicate that you have a different problem).
You can use Redis for storing jwt label. Redis is much faster and convenient for storing such data. The request to Redis should not greatly affect the performance. You can try the library jwt-redis
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With