DEV Community

Secure Your Node.js Application With JSON Web Token

Marc Backes on August 13, 2019

Cross-posted from CodeWall When you build a web application where your front-end and back-end is separated, one way of putting it behind a login is...
Collapse
 
ssimontis profile image
Scott Simontis

Thank you good sir! I love the way you explored this concept. Authentication has become a black box to most developers these days. Don't get me wrong, services like Azure AD and Auth0 are awesome and great for quick prototyping, but I feel many developers are so used to having authentication abstracted away that they don't really understand what is going on and all. Thank you for reminding everyone that the token is not encrypted and needs to be checked every time.

The only frustrating thing with JWT is revocation, mainly because it's impossible. If you are building a security-critical app where user rights may need to be revoked at any time, JWT may not be the best choice. The workaround is to maintain a revocation list in the database, preferably with the most recent revocations in a cache, and to check the token against the revocation list.

Collapse
 
mikedshaffer profile image
Mike Shaffer

We had the exact scenario and used JWT very successfully. You state it exactly, create a server based revocation list. In a database, memory cache...whatever. On any incoming requests you will have verify() method to you know, verify the JWT. As one of the many steps of verify(), ensure that the user is not in the revocation list. If they are, the request is denied and a response of unauthorized is generated. We also had a requirement that each login could be revoked. In that case we added a unique serial number (actually a timestamp) to the body of each JWT. Added a check to the verify() method to look up the serial number. We then managed both of these list with time to live and fast caching to ensure performance. And this was all for a Fortune 50 Financial Services company with millions of users world wide.

Collapse
 
rishpoddar profile image
Rishabh Poddar

This sounds awesome! I have a question though:
What does the unique serial number achieve that blacklisting the JWT doesn't?

By the way, if you are interested in adding more levels of security while maintaining scalability, have a look at supertokens.io. It's one of the most extensive and well thought out solutions that prevents against all session attacks including detecting session hijacking using rotating refresh tokens. Also, this solution is end to end, taking care of all race conditions and network failure issues, so that developers have a very easy time implementing it. For details on how this works, please visit: supertokens.io/blog/the-best-way-t...

Thanks!

Collapse
 
themarcba profile image
Marc Backes

Wow, this is an amazing story. I see you added some extra steps, which is really cool. Gives me the idea to add a revocation status to my users as well. 👍

Collapse
 
themarcba profile image
Marc Backes

First, thanks for your kind words. I appreciate the encouragement a lot 🤗

I always add generated tokens to the user object, so they could themselves remove other logged-in sessions (upon login I check for users with the given id AND token in user object). To block someone, you can delete all their existing tokens and set a flag in the user object to deny any further token generation.

I could write up another blog post on this when I get some time

Collapse
 
brokenthorn profile image
Paul-Sebastian Manole

Read some blogs but basically you need to issue JWT renewals based on previous payload or token and that way maintain a session if needed or at least maintain a chain of tokens but renewal requests need to be issued by the client before current token expires otherwise you can't have secure renewals.

Collapse
 
themarcba profile image
Marc Backes

I don't know about the best practices about this case, but here is my opinion about it:

You can store the critical workflow data somewhere in the database, attached to the user. Then when he logs in (again), you can pull the information from there.

However, this should not happen very often. If users find themselves getting logged out much by token expiration, I'd recommend just adjusting the expiration time accordingly.

Alternatively, you can show a message, warning the user that in x minutes the session will be closed.

Collapse
 
jitheshkt profile image
Jithesh. KT

Great write up! Sad that it doesn't have any information about refresh token or building a logic to refresh the token securely when it expires that too without kicking the user out.

Collapse
 
pavelloz profile image
Paweł Kowalski

Thank you very much for excellent explanation.

Collapse
 
themarcba profile image
Marc Backes

I am glad I could be of service 😊 Enjoy coding!

Collapse
 
vikaschauhan1 profile image
Vikas Chauhan

I want do develop it in a way that no body can decide it as happens in this case.
Could you please tell me the best solution for this?