What the JWT?
JSON Web Tokens have seen widespread adoption. There are copious resources online describing how to adopt JWTs. StackOverflow is cramped with JWT code snippets. What I feel doesn't get addressed enough, is why engineers love them. Because we do love them. We love them because they eliminate a scalability obstacle.
The challenge
Alice wants to start using your product. She already has an account, so she logs in. She enters a password; or a code sent in a text; or an OTP from an authenticator app; or a combination thereof. This satisfies the server ‒ Alice' identity is confirmed.
HTTP is inherently stateless. Yet, Alice would not enjoy repeating the authentication process over and over. She wants to remain logged in for a while. The server must send a token to Alice with which she can prove her identity in future requests.
Random tokens and signed tokens
For most engineers, the intuitive solution would be to use sessions. PHP introduced sessions in the early '00s. This is when I first learned about this design, and I loved how simple it was. The token sent to Alice is the session ID (in PHP, it's PHPSESSID
). This token is (pseudo-) random. The server keeps a record of the tokens and the users they identify.
The downside to this design is that it requires a central storage of tokens. As your product scales up, the original single server will be replaced by a swarm of servers. Every one of those servers will likely want to know who's on the other end of the line, and thus must check the token storage.
Setting up a central token storage is achievable, even at scale. However, signed tokens ‒ such as JWTs ‒ remove this need altogether. See, signed tokens are self-contained. Providing that a server knows the secret or public key, it can validate a token by merely looking at the token itself. No central token storage necessary. And the fewer dependencies between nodes in the ecosystem, the less complex the scaling puzzle.
(For an understanding of signed token validation, look into HMAC.)
The security aspect
"But couldn't an attacker spoof a valid token?", you might ask. They could. Just like they could theoretically guess a random token. But when a strong secret or public key is used, safely kept from the attacker, they would have to be exceptionally lucky. Unrealistically lucky.
Signed tokens do have an actual security disadvantage. Random tokens can be revoked immediately (by dropping them from the token storage); signed tokens remain valid until they expire. Short-lived signed tokens enable faster revoking, but by design it is not instant. Some engineers have suggested keeping a list of revoked tokens. This reintroduced the need for a central storage (albeit for revoked tokens), negating the advantage of using signed tokens. To use signed tokens is to accept this limitation.
Consider your options
At Nullhouse we love JWTs and signed tokens. They can help your product scale by reducing the amount of wires required. This does not mean signed tokens are the go-to solution for every scenario we encounter. It is important to understand and consider the pros and cons of the different approaches. Choose the solution that best fits your problem.