JWT Tokens: The What, How, and Why
When I first learned about the processes of encryption, authorization, authentication, cookies, JWT tokens, etc., I was pretty overwhelmed. Getting into the weeds of these topics is extremely complex and can be confusing, which is why cybersecurity is an entire field in itself. But gaining, at the very least, a surface level understanding of these topics is important as a developer.
In this article, we’ll gain an understanding of something that is becoming a very popular method of authorization, JSON Web Tokens (JWT).
While the topics in this article don’t even scratch the surface of cybersecurity, they’re very important to understand and be aware of as a software developer.
Key point: Understanding the security process is an important part of being a developer.
What’s the Difference Between Authentication and Authorization?
To put it simply, authentication is the first step in any security process. This beginning process verifies credentials (an example being a password or the facial recognition on your phone) and confirms the user is who they say they are. Authorization (where JWT comes into play) gives the user access to specific functions or resources. An example could be authorizing that the user has access to financial records, if they can perform admin actions, etc.
A simple definition from an article from okta.com:
“Authentication confirms that users are who they say they are. Authorization gives those users permission to access a resource.”
In other words, authentication is the bouncer at the club checking your ID to make sure you’re 21 and allowed in the building; authorization is the stamp he gives you to allow access back into the club or confirming you’re allowed in the VIP area.
Key point: Authentication validates a user and authorization gives the user access to specific functions or resources.
To understand why JWT is useful and how it’s different, we need to have a brief understanding of another method of authorization: cookies.
- A user logs in to a site (is authenticated) from their browser (known as the client).
- The server saves their session in server memory and assigns a unique session ID that corresponds with that part in memory.
- The server then sends this session ID back to the client as a cookie. This way, the browser always has access to the session ID and is able to send it to the server any time it makes a request.
- Now a user tries to access a page. The browser then sends a request with the session ID cookie to the server.
- The server receives this ID and checks to see if it exists in memory. Once the server sees the ID exists in memory, it checks to see if the user with that ID is authorized to access the page, function, etc., they’re trying to access.
- The server then sends a response back to the client saying if they’re authorized for this action or not, and the browser acts accordingly.
Where Does JWT Come In?
The beginning of a session that uses JWT for authorization starts similarly, but then there are some key differences.
Here’s an example of a session that uses JWT tokens for authorization rather than cookies:
- A user logs in to a site (is authenticated) from their browser (known as the client).
- Now, instead of the server storing the user’s session in server memory, it creates a JSON Web Token, encodes it, serializes it, and signs it with a unique secret key. This secret key allows the server to know if the token has been tampered with.
- The server then takes the JWT and sends it back to the browser. The main difference here: Nothing is stored on the server. The JWT has all the necessary information about the user built into it.
- The browser then stores the JWT token (a common way is by using the browser’s local storage).
- The user then tries to access a page, and the browser sends a request with the JWT (similar to what was done with the session ID cookie in the example above) to the server so it knows which user is requesting authorization.
- The browser then checks the secret key it gave the JWT in the very beginning to make sure it wasn’t changed. This way, if the user changed the user in that JWT token, the server will know and say it’s invalid.
- Once confirmed that the JWT is valid, the server then sends a response back to the client saying if they’re authorized to perform the requested action or not (similar to above).
The main difference to notice here is that with cookies, the information is stored server-side, while with JWT, since the information is stored in the actual token, the information is stored client-side. Since the server doesn’t need to remember anything, this simplifies things a lot, especially when working with multiple servers and having different sessions.
Key point: A key difference between cookies and JWT tokens is that cookies are stored on the server, while JWT tokens are stored client-side.
How Do JWT Tokens Work?
Let’s take a trip to jwt.io and break down what we see.
On the left, we have the encoded version of the JWT, which is what is sent to and from the client.
On the right, we have the decoded version, which has three different parts:
- The Header, which determines the algorithm used to encode and decode the token (the different algorithms are outside the scope of this article and, honestly, very rarely necessary to change).
- The Payload, which is all the information that is stored in the token.
- The Signature, which is how the server verifies the token hasn’t been changed by the client before sending it back.
You’ll notice that the JWT separates these three parts with periods, making them easy to identify.
As mentioned above, discussing the different types of algorithms that can be used in the header is outside the scope of this article. The important thing to know here is that this is what is used to decide how the token is encoded and decoded.
The payload is where all the data on the user is stored and is the bulk of what your application is in charge of. Any key/value pairs can be put in this component, but there are some common fields you’ll see:
sub(or subject) is usually the ID of the user being authorized.
name. This may come as a shock but the name is usually the name of the user.
iat, which stands for “issued at.” This says when the token was created. This can be useful if you want to expire tokens (often saved as
eat, which stands for “expired at”).
The signature verifies the user did not alter the token before it was sent back to the server.
This is the way it creates the signature:
- It takes the header and adds a period.
- It takes the payload and combines it with the header (after the period).
- It uses the algorithm defined in the header to encode the above-combined data using the secret key you define (the area where it allows you to type in the picture above).
- This means that if the client alters even one character from the data, the signature won’t match anymore when it’s sent back to the server.
Why Use JWT?
Let’s say a company owns two servers (apps, websites, etc.), for two different aspects of their business (or maybe it’s a huge business that can’t store all their users on one server, so it balances traffic between different servers). The company wants users who are logged in on one app/server to be automatically logged in to the other app/server should they switch over to it (this is often done seamlessly, without the user even noticing). They don’t want the user to have to log back in when switching over to the other server.
In a session-based server (cookie-based), since the session data is stored in the server’s memory and not in the browser, the user would need to log in separately on each server because the session is stored in one but not the other.
When using JWT, since the token is stored in the browser and not on the server, if you share the same secret key on both servers, then all you need to do is send the same JWT to each. This means the client can stay logged in, even when switching between servers.
Using JWT tokens allows the user to switch between servers without requiring a login each time they switch.
- Authentication is what verifies the user is who they say they are.
- Authorization gives the user access to certain functions and resources. This is where JWT tokens come into play.
- Cookies are a method of authorization that uses a session ID stored on the server.
- The most important reason JWT tokens are different from cookies is that they store the information client-side. The server doesn’t need to store anything.
- JWT tokens have three different parts: the Header, which stores the algorithm used for encoding and decoding the token; the Payload, which stores all of the user information; and the Signature, which is how the server verifies the token hasn’t been altered.
- Since JWT tokens are stored client-side, they are especially useful when you want to use multiple servers without the client needing to log in separately when switching between them.
Have anything else to add about JSON Web Tokens, authentication, or authorization? Feel free to share in the comments!