JWT Explained

What is JWT? Understanding JSON Web Tokens for API Security

Have you ever wondered how apps keep your data secure while you’re logged in? JSON Web Tokens (JWTs) play a crucial role in modern authentication and authorization. In this post, we’ll break down what JWTs are, how they work, and why they’re essential for API security.

What is JWT?

JWT stands for JSON Web Token. It’s a compact, self-contained way to securely transmit information between parties. What makes JWTs particularly powerful is that they are digitally signed, making them verifiable and tamper-proof. JWTs can be signed using:

  • HMAC (Hash-based Message Authentication Code) with a secret key
  • RSA or ECDSA for public/private key encryption

This allows JWTs to be trusted and validated without needing to store session data on the server.

What is JWT Used For?

JWTs are widely used in modern applications for two main purposes:

1. Authorization

JWTs are commonly used for authorization, not authentication. Authentication happens when a user logs into an authentication server (Identity Provider, or IdP). Once authenticated, the server issues a JWT, which the user includes in subsequent requests to access protected resources.

2. Information Exchange

JWTs provide a secure way to exchange information between parties. Since they are signed, the recipient can verify the authenticity of the sender and ensure that the data has not been altered.


JWT Structure

A JSON Web Token consists of three parts, separated by dots (.):

  1. Header
  2. Payload
  3. Signature

Together, these form a compact token like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpv
aG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Let’s break down these components.

🚀Boost your career with Full Stack Software Developer Certificate 👉

1. Header

The header typically contains two pieces of information:

  • Type (typ): Specifies the token type, which is JWT
  • Algorithm (alg): Defines the signing algorithm (e.g., HS256, RS256)

Example:

{
"alg": "HS256",
"typ": "JWT"
}

The header is then Base64Url encoded to form the first part of the JWT.

2. Payload

The payload contains claims, which are statements about the user or other relevant data. Claims are categorized into three types:

  • Registered Claims: Predefined claims like issuer (iss), expiration (exp), subject (sub), and audience (aud)
  • Public Claims: Custom claims that should use collision-resistant namespaces
  • Private Claims: Claims created for communication between specific parties

Example:

{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}

The payload is Base64Url encoded to form the second part of the JWT.

Note: JWT payloads are not encrypted, only signed. Anyone can decode and read the contents, so avoid storing sensitive information in them.

3. Signature

The signature is used to verify the authenticity of the token. It’s created by taking:

Base64Url(header) + "." + Base64Url(payload)

Then, it is signed using the algorithm specified in the header and a secret key (for HMAC) or a private key (for RSA/ECDSA).

For example, with HMAC SHA256, the signature is:

HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)

The final JWT consists of:

Header.Payload.Signature

How JWT Works in Authentication and Authorization

While JWTs themselves are not authentication mechanisms, they play a crucial role in authorization. Here’s how they typically work:

1. User Logs In

A user logs into an authentication server (e.g., Auth0, Firebase, Cognito) using their credentials.

2. Server Issues a JWT

Once authenticated, the authentication server generates a JWT and sends it back to the user.

3. User Sends JWT with Requests

The client includes the JWT in the Authorization header when making requests to a protected API:

Authorization: Bearer <JWT>

4. Server Verifies JWT

The API server validates the JWT using the public key (for RS256) or the shared secret (for HS256). If valid, the request is processed; otherwise, access is denied.


Security Considerations for JWT

JWTs are powerful, but they must be used securely. Here are some best practices:

Use Secure Algorithms
Prefer RS256 (asymmetric) or ES256 over HS256 (symmetric) to enhance security.

Always Use HTTPS
Transmit JWTs over HTTPS to prevent interception.

Set Expiration Times
Use short-lived tokens (exp claim) to limit exposure in case of a token leak.

Store Tokens Securely
Avoid storing JWTs in local storage as it is vulnerable to XSS attacks. Instead, use HTTP-only cookies or secure storage mechanisms.

Don’t Store Sensitive Data in JWT
JWTs can be decoded easily. Never store passwords, secret keys, or personally identifiable information (PII) in them.


Real-World Example of JWT

Let’s visit jwt.io and explore an example JWT.

  1. A simple JWT might contain:
    • Header specifying alg: HS256
    • Payload containing claims like sub (user ID) and iat (issued time)
    • Signature generated using a secret key
  2. A JWT issued by Auth0 will have additional fields like:
    • kid (Key ID)
    • iss (Issuer, e.g., https://auth0.com/)
    • aud (Audience, the app this token is meant for)
    • scope (Permissions granted)

Conclusion

JWTs provide a stateless, scalable, and secure way to manage authorization and information exchange in modern applications. They help verify users without storing session data on the server, making them ideal for API authentication and OAuth-based access delegation.

By following best practices, you can effectively use JWTs to secure your API endpoints.

📌 Next Steps
Now that you understand how JWTs work, let’s implement them in a real-world project. Check out my next blog post, where we’ll secure a Node.js API with JWT authentication! 🚀

Share this article

Similar Posts