My disenchantment with JWT based Authentication
October 12th 2020 on Dušan's blog
Ah yes, JWT, a stateless, cryptographic, secure authentication mechanism. Except I no longer use it for authentication, here's why.
- It's a headache to setup.
- There is no elegant way of revoking tokens.
- More often than not you end up building some unnecessarily complicated refresh token mechanism.
- It had some real security oversights in the past.
- The tried and true method of session based authentication has been around since the dawn of all time.
Let's break down each of the points I made to remove any uncertainty you may have.
A headache to setup
Maybe one of the most daunting tasks I have ever done as a software engineer. There are several things one must do right for JWT to be secure and reliable, including but not limited to:
- Generating keys
- Deciding whether to use symmetric or asymmetric encryption
- Deciding what algorithm to use (RSA, HMAC...)
- Finding a library you can trust that has a relatively simple API
- Wiring everything up
These reasons are already enough for me, but if you haven't yet been convinced let's continue.
No elegant way of revoking tokens
We've all been there, JWT is stateless so it shouldn't be stored, yet we want to be able to revoke the token in case of misuse. More often than not people end up storing the token in some sort of database, resulting in complete and utter defeat of its purpose as a stateless authentication mechanism.
What I'd like to call a hack, refresh tokens are used in a misguided attempt to secure the JWT by making it last for some short amount of time (usually minutes), then requiring the client application to send a refresh token as a means to obtain a new JWT. Needless to say the focus should be on alleviating any potential security vulnerabilities that a client may suffer from (XSS, CSRF just to name a few) in order to prevent token stealing in the first place.
Security oversights in the past
An article I linked next to this point explains this at length.
Session based authentication exists
Sessions have been around since the dawn of time and they are not going anywhere. They are easy to implement on both client-side and server-side. The browser already sends all cookies to the server with each request so a client has to do exactly nothing to send the session cookie to the server. A server reads the session cookie and pulls the relevant information from a database or a file with the included session id. More often than not this is abstracted away from the developer either by some library or a language construct.
For all the reasons I listed above I'm moving away from JWT based authentication. While sessions have some inherent limitations (They don't work at all with native mobile apps for example), for the nature of my work they are enough and don't cause me to pull every single strand of hair out of my head. Remember that the major factor in application security isn't technology it's the human factor. As developers we are required to do our homework and properly secure our applications.