Authorization with JSON Web Tokens
May 02 2016
APIs need to verify who you are and what you’re allowed to do. JSON Web Tokens or “jots” provide a standardized means for accomplishing this.
This article explains the underlying mechanics of how JWTs simplify authorization and authentication.
So What’s a JWT?
It’s a tamper resistant JSON object. It might not seem that way at first, given a JWTs strange appearance.
Here’s an example JWT:
On the surface, that just looks like a string of nonsense with three dots in it. You might have expected to see a traditional JSON object with some key value pairs attached to it. The reason for the scrambled appearance is that JWT strings are Base64 Encoded. This reduces the risk of encoding issues over a transmission channel.
btoa global functions.
That explains why a JWT doesn’t immediately look like JSON, but we’re not quite done yet. What’s going on with those three dots in the token?
The Format of a JWT
Text that once appeared to be garbage text was actually just Base64 encoded JSON.
In the case of JWTs, the text is further broken down into 3 sections separated by a period. The sections follow the format of
You can try this out in your browser with the token from the previous section:
Let’s take a deeper look at theses 3 sections of the JWT.
Section I: The Header
The first part of our JWT looked like this after decoding:
The first part any JWT is the “header”.
Just like HTTP headers, JWT headers are a storage area for meta data.
In the token above, we’re letting the user know that this is a JWT (
"typ" : "JWT").
The other header (
"alg": "HS256") indicates the encryption scheme used to sign the token. We’ll cover that later in section III.
Section II: The Payload
The next part of a JWT is the “payload”. Like the header, it too is a set of key/value pairs.
JWT users refer to these pairs as “claims”. As the name suggests, it conveys information in a verifiable manner.
JWTs are a sort of “sworn statement” made by your server.
Some example claims:
In this example, the server can verify authenticity thanks to cryptographic signing.
header, it is Base64 encoded JSON.
Certain claim names are reserved by the JWT spec, so be careful! For example, the reserved claim
iat indicates the “issued at” time of a JWT. See the JWT specification for a full list.
Section III: The Signature
If claims were changeable, they would be of no use to developers. Changing privilege levels or identity is a dangerous situation in web applications.
JWTs are tamper resistant through the use of a cryptographic signature. The signature is an encrypted version of the
payload joined together by a
A JWT is invalid when modified, even by one character. All major JWT libraries provide this verification functionality. Most libraries raise a runtime exception
By using public key encryption, users can verify the integrity of tokens without being able to change them.
Here’s a pseudo code example:
Like any other tool, there are minor “gotchas” to be aware of.
Payloads are human readable. Never store an unencrypted user password in a JWT, or anywhere else for that matter.
The “ALG” header is for reference purposes. Never trust it on the backend. There have been many attacks against the “ALG” claim in the past. The most common is setting the
alg header to
none. The safest way to avoid this attack is to never trust user provided
JWTs are stateless. In theory, you don’t need to store a copy of the token on your server. This eliminates the need for server side token storage. But how do you handle revocation of compromised tokens? Consider adding a “JTI” (token identifier) claim for such use cases.
The JTI claim serves as a unique id for a each token. Providing a unique ID for tokens enables creation of server side whitelists or blacklists.
Consider adding an expiration date. Adding an
EXP (expiration time) claim to a token is always a smart idea. The
exp claim is a time stamp (integer) that the server verifies to ensure a token is still active.
JWTs are one of the easiest authorization solutions out there. It’s worth reiterating some of the key benefits:
JWTs follow a standard. You don’t need to re-invent the authentication wheel for every project. The JWT specification does a great job of keeping things standardized.
JWT claims can be stored on the client, since they are tamper resistant. This is known as “stateless authentication”.
JWTs provide more granular permission levels over traditional string tokens because claims are configurable. You can enclose permission information in the token itself.
Transmission over numerous channels is possible since tokens are base64 encoded. It is possible to place JWTs in HTTP headers, URLs, emails, carrier pigeon, etc.
Drop us a line in the comments if you have any questions. If you enjoyed the article, consider signing up for our non-spammy, once-a-month-only-I-promise newsletter.