
.png)
JWT stands for JSON Web Token, though most people just pronounce it ‘jot.’
JWTs offer a fantastic alternative to standard session-based authentication cookie methods by providing all the information an application needs to authenticate and authorize a user’s session in a handy Base64 encoded stateless token that is stored completely on the client side.
In this article, we’re going to break down:
.png)
To put it simply, JWTs are compact, stateless tokens used to authenticate and authorize a user’s requests in an application or website.
Once encoded and signed, a JWT has three parts, each separated by a period:
*Note: While JWTs are Bas64 encoded, they can be decoded. A JWT’s signature prevents tampering but does not hide its contents. Do not put secret information in the payload or header elements of a JWT (such as a password) unless it is encrypted.

Some Pros to JWT Tokens include:
Some Cons to JWT Tokens include:
Before diving into JWTs, let’s clear up a common mix-up:
Authentication answers “Who are you?”. The server uses your credentials to prove that you are, in fact, who you say you are. Like logging in with the correct username and password.
Authorization answers “What are you allowed to do?”. Now that you’re logged in, which resources do you actually have access to? For example, are you just a user, or are you allowed admin access?

Session-based authentication is fine for small-scale applications but becomes more and more complex with multiple servers or microservices. Since session data is stored on the server, every server needs access to a single-source of truth in order to validate active sessions. Without the servers being in sync, discrepancies can occur, which leads to unrecognized sessions and failed user requests.
Session based storage solves this problem by allowing us to save sessions to a database or a centralized session store which holds the session information in one place so all the servers can access it. However, this adds a layer of complexity because more databases = more overhead.

With all this in mind, JWTs were created to mitigate many of the challenges that come with scaling large applications in a session based cookie system.
Now that we understand Session-Based Authentication, let’s take a look at how JWTs streamline session management by taking a look at the way a JWT Authentication Flow works:

A JWT is a string with three sections separated by periods (.):
This contains metadata about the token (ie: type = JWT, algorithm = HS256 or RS256).

This is made up of key/value pairs called “claims” which contain metadata about the user or the token itself like user ID, role, expiration, and any other data you may want the JWT to hold on to. Claims can be custom (private), registered, or public.
There are three types of Payload claims that are important to know: Registered, Public, and Private. If a system consumes multiple JWTs from multiple companies and those companies use the same claim key name with different meanings, it causes misinterpretation known as collision. For instance if two companies use “role” as a payload claim, and one company means “admin” or “user” while the other company means a person’s “job title”, the consuming system could misapply authorization logic.
In an effort to avoid this wherever possible, the Internet Assigned Numbers Authority (IANA) maintains a registry of standard claim names. Some examples of Registered Claims include iss (issuer), sub (subject), and exp (expiration time). You can view the full list of registered claims at iana.org.
Public claims are custom claims defined in a JWT payload with the intention of sharing across multiple systems or microservices, usually within the same organization. For instance, if a massive conglomerate owns multiple major social media sites with users who register to one or the other or both, this information needs to be sent in the payload. The claim should have a unique prefix tied to a namespace to avoid collision. For instance, a Public Claim in a JWT payload should look like this: “https://mysocialmediasite.com/role”: “admin”.
Private Claims are also custom claims, but they are not meant to be used across many systems, they are meant for internal use within a company. For example, developers for an e-commerce platform might use “cartID”: “94b12fae-4c67-4f59-b4gh” to track a customer’s active shopping cart between frontend and backend services. There’s no need to register or namespace it, because this claim is only meaningful within the system and will not be subject to collision.

This is what makes JWTs so fantastic! It’s created by hashing the header and payload with a secret or private key. If anyone tampers with the data on the JWT, the signature no longer matches, and the session automatically expires which will require the user to log in again.

Single Sign-On (SSO): A user can authenticate just once and then use that same token to access multiple independent applications or services. That’s why JWTs are a common choice in OAuth2 and OpenID Connect systems. Like when you sign into an application through your Google account!
API Authentication: JWTs are often used as Bearer tokens in API requests which means microservices (like adding items to a cart) or client applications (like those in your browser) to prove their identity without having to maintain server-side sessions. For example, on your bank app, when you click to see your account balance, the JWT can be sent as a Bearer token in the Authorization header of the request for that page and data. That way, if the JWT is valid and hasn’t expired, you can view your balance. Otherwise, the app will require you to sign back in.
Note: If you’re having a hard time picturing where the Authorization header is in an HTTP request, check out our article on the JavaScript fetch API.
Mobile Apps & SPAs: In browser based applications, cookies are stored on the browser, in mobile apps they’re not (unless the app uses WebView which does have its own cookie storage). That makes cookie-based sessions difficult to manage. Instead, the JWT is usually stored in secure storage and gets sent as a Bearer token in every HTTP request that requires authentication.
JWTs support a variety of use cases, including login authorization and secure API communication. For the purposes of this tutorial, the focus will be limited to the login flow using Express and Node.js, then we will test the setup with Postman.


Let’s test out this JWT flow in Postman:

Click the “Cookies” tab to find the JWT we sent in our response! We will use this to access our “user profile” information (username and hairColor) in a moment.

We can either copy from the Cookies tab in the response section as seen above, or from the cookies tab in our request section as seen below.

Copy the JWT from the cookie.

Our JWT, it will be sent with every request from the browser in the form of a cookie. But, remember not all apps send JWTs this way. Instead, we can send it as a Bearer token by adding it as an Authorization header. Now that we have our JWT copied, navigate to the Authorization tab.

Now, paste it in as a Bearer token in the Authorization header.

Switch the request to ‘get’ and change the url to http://localhost:3000/profiles.

And now in the response body, we see our user’s profile information as sent from the server!

We couldn’t write an article about JWTs without mentioning refresh tokens. As we explained, you can configure the expiration for your JWT (access token). But, remember, if someone has access to your JWT, they can access your information on the server. This is where refresh tokens come in.
Using one JWT as your access token for a long period of time is dangerous. Instead, you can also create a refresh token that will be used to get a new access token once the last access token has expired. Refresh tokens can last days, weeks or even months.
But wait! Can’t someone steal your refresh token and continue to generate new access tokens as long as that refresh token is valid? Yes. That’s why refresh tokens are meant to live longer than regular access tokens, but not forever. They limit the window of opportunity for abuse. Each time a client uses a refresh token to get a new access token, your server should issue a new refresh token and invalidate the old one.
Refresh tokens can be created the same way as any other JWT and stored centrally (in a database for example). Since they are used far less frequently than access tokens, it’s still a more efficient process than session-based management in terms of storage.
JWTs are one of the most widely used forms of authentication today. They are stateless and ensure quick access to scaled up, distributed systems, and applications with many microservices. JWTs are extremely efficient and scalable, but they are not a one-size fit all authentication fix. As with all technologies, it is important to consider your particular system’s design. Consideration should also extend to revocation strategies, claim design, and storage practices in order to strengthen your system’s design, because a poorly created JWT can easily make your application susceptible to attackers. With all these considerations in mind, a well crafted JWT might just be what you need to scale your application to the next level.
You can send it with every request to a server, either as a Bearer token in the header or in an httpOnly cookie.
JWTs scale better across large, distributed systems and avoid centralized session stores. If an application uses several servers, instead of storing your session information in a database, they can use JWTs which are stored on the client and contain all the information needed for authorization.
Not exactly. API tokens are a string of characters you can include in your API request. In this case, the server would have a database of valid tokens. If your token matches one in the database, the request succeeds. JWT is a format often used for API tokens, but not all API tokens are JWTs.
Base64 encoding can easily be decoded by anyone with access to the internet. For that reason, you should never add sensitive data to any part of your JWT.
JWTs can only be revoked if the token expires or the server registers that the signature has been tampered with in the process of verifying a user’s response. It is difficult to stop a JWT once it is in motion, so it is best practice to implement the use of refresh tokens and to keep expirations limited to minutes or at most a few hours.
JWT stands for JSON Web Token.

Explore CS Prep further in our beginner-friendly program.
Get more free resources and access to coding events every 2 weeks.

Connect with one of our graduates/recruiters.

Our graduates/recruiters work at:

Everett and Alex Stewart are proud Codesmith alumni who bring creativity and storytelling into the world of software development. Everett, a software engineer and content creator with a background in media production, transitioned into tech to combine problem solving with human-centered creativity. When Everett is not contemplating life near a large body of water, you can find him writing code, producing content, or jamming on guitar. Alex is a former professional actor turned developer. His passion lies in making tech fun and accessible through talks, tutorials, and blogs, drawing on his experience as a performer as well as with JavaScript, React, and Node/Express. Together, they are committed to creating technical content that resonates both technically and creatively.

Connect with one of our recruiters to learn about their journeys.
Our graduates/recruiters work at: