Documentation & Learning Resources
Back to Tool

JWT Fundamentals: Understanding JSON Web Tokens

Core Concepts Reading time: 10 min

What is a JWT?

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed.

JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA. Signed tokens can verify the integrity of the claims contained within them, while encrypted tokens hide those claims from other parties.

JWT Structure

A JWT consists of three parts separated by dots (.):

xxxxx.yyyyy.zzzzz

These parts are:

  1. Header - Contains metadata about the token
  2. Payload - Contains the claims or assertions
  3. Signature - Verifies the token hasn't been altered

Let's examine each part in detail:

Header

The header typically consists of two parts:

  • The type of token, which is JWT
  • The signing algorithm being used, such as HMAC SHA256 or RSA

Example:

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

This JSON is Base64Url encoded to form the first part of the JWT.

Payload

The payload contains the claims. Claims are statements about an entity (typically, the user) and additional data. There are three types of claims:

  1. Registered claims: Predefined claims which are not mandatory but recommended
    • iss (issuer): who issued the token
    • sub (subject): who the token refers to
    • aud (audience): who the token is intended for
    • exp (expiration time): when the token expires
    • nbf (not before): when the token starts being valid
    • iat (issued at): when the token was issued
    • jti (JWT ID): unique identifier for the token
  2. Public claims: Claims defined by those using JWTs
  3. Private claims: Custom claims created to share information between parties

Example:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022,
  "exp": 1516242622
}

This JSON is Base64Url encoded to form the second part of the JWT.

Security Note: The payload is only Base64Url encoded, not encrypted. Anyone can decode it to view its contents. Never put sensitive information like passwords in the JWT payload unless you're using JWE (JSON Web Encryption).

Signature

The signature is created by taking the encoded header, the encoded payload, a secret, and the algorithm specified in the header, and signing them.

For example, if you're using the HMAC SHA256 algorithm:

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

The signature is used to verify that the message wasn't changed along the way, and, in the case of tokens signed with a private key, it can also verify that the sender of the JWT is who it says it is.

JWT Encoding Process

  1. Create a header JSON object
  2. Create a payload JSON object
  3. Base64Url encode the header
  4. Base64Url encode the payload
  5. Create a signature using the encoded header, encoded payload, and a secret
  6. Concatenate the encoded header, encoded payload, and signature with dots
1

Header

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

Base64Url Encoded Header

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
3

Payload

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

Base64Url Encoded Payload

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
5

Signature

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

Complete JWT

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT Verification Process

  1. Split the JWT into its three parts
  2. Base64Url decode the header and payload
  3. Verify the signature using the algorithm specified in the header
  4. Check the claims (exp, nbf, iss, etc.) to ensure they're valid
  5. Process the JWT according to the application's requirements

JWT vs. Session Tokens

Feature JWT Session Tokens
Storage Client-side Server-side
Scalability Highly scalable (stateless) Requires session storage
Security Signed, can be encrypted Opaque reference
Size Larger (contains claims) Smaller (just an ID)
Expiration Self-contained Controlled by server
Revocation Difficult without a blacklist Easy (delete from store)

Common JWT Use Cases

Authentication

After a user logs in, each subsequent request will include the JWT, allowing the user to access routes, services, and resources that are permitted with that token.

Information Exchange

JWTs are a good way of securely transmitting information between parties because they can be signed, which means you can be sure the senders are who they say they are.

Authorization

Once a user is logged in, an application can allow access to specific resources based on permissions encoded in the JWT.

Federated Identity

JWTs are used in single sign-on (SSO) scenarios where a user logs in once and gains access to multiple systems without being prompted to log in again.

JWT Best Practices

Security

  1. Use HTTPS: Always transmit JWTs over HTTPS to prevent token theft through network eavesdropping.
  2. Set Proper Expiration: Use short-lived tokens (minutes to hours, not days) to minimize the damage if a token is compromised.
  3. Validate All Claims: Always validate the issuer, audience, expiration, and other claims.
  4. Use Strong Secrets/Keys: For HMAC algorithms, use a strong, randomly generated secret. For RSA/ECDSA, use proper key lengths.
  5. Consider Using Refresh Tokens: Implement a refresh token system for obtaining new access tokens without requiring the user to re-authenticate.

Implementation

  1. Don't Store Sensitive Data: JWTs are not encrypted by default, so don't store sensitive information in the payload.
  2. Implement Token Revocation: Have a strategy for revoking tokens when needed (user logout, password change, etc.).
  3. Use Appropriate Algorithms: Prefer asymmetric algorithms (RS256, ES256) over symmetric ones (HS256) for production systems with multiple verification points.
  4. Validate Input: Always validate and sanitize user input before including it in a JWT.
  5. Handle Errors Securely: Don't expose detailed error messages that might help an attacker.

Conclusion

JWTs provide a powerful, standardized way to handle authentication and authorization in modern applications. By understanding their structure, capabilities, and security considerations, you can implement them effectively and securely in your projects.

Remember that while JWTs offer many advantages, they're not a silver bullet for all authentication scenarios. Consider your specific requirements and security needs when deciding whether to use JWTs or alternative authentication mechanisms.