JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained method for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs are a popular choice for API security and authentication in modern web applications.

📋 Table of Contents

Key Takeaways

  • Structure: A JWT consists of three parts: a header, a payload, and a signature, separated by dots.
  • Self-Contained: The payload contains claims about the user (e.g., user ID, roles), reducing the need for database lookups.
  • Security: The signature is used to verify the token's integrity, ensuring it hasn't been tampered with.
  • Statelessness: Because the token is self-contained, JWTs allow for stateless authentication, where the server doesn't need to store session state.
  • Common Use Cases: Ideal for API authentication, microservices, and secure information exchange between parties.
  • Implementation: Libraries for creating and verifying JWTs are widely available in languages like JavaScript, Python, and Java, simplifying integration.

Ready to work with JWTs? Our online tool provides an easy way to decode, encode, and inspect your tokens.

Try the JWT Decoder/Encoder tool now

The Anatomy of a JWT

A JWT is composed of three parts, separated by dots (.):

  1. Header: Metadata about the token.
  2. Payload: The claims or data.
  3. Signature: For verifying the token's integrity.

A typical JWT looks like this: xxxxx.yyyyy.zzzzz.

1. Header

The header specifies the token type (JWT) and the signing algorithm used, such as HMAC SHA256 or RSA.

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

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

2. Payload

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

  • Registered Claims: Predefined claims like iss (issuer), exp (expiration time), sub (subject), and aud (audience). These are recommended for interoperability.
  • Public Claims: Custom claims defined by developers, which should be registered in the IANA JSON Web Token Registry to avoid collisions.
  • Private Claims: Custom claims created for specific use cases between parties that have agreed on their meaning.

Example payload:

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

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

3. Signature

The signature is created by combining the encoded header, the encoded payload, a secret key, and the algorithm specified in the header.

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

The signature ensures that the token has not been tampered with and, in the case of a private key signature, verifies the sender's identity.

Code Examples

JavaScript (Node.js)

const jwt = require('jsonwebtoken');

// Encode (Sign)
const payload = { sub: '1234567890', name: 'John Doe' };
const secret = 'your-secret-key';
const token = jwt.sign(payload, secret, { expiresIn: '1h' });

// Decode (Verify)
const decoded = jwt.verify(token, secret);

Python

import jwt

# Encode
payload = {'sub': '1234567890', 'name': 'John Doe'}
secret = 'your-secret-key'
token = jwt.encode(payload, secret, algorithm='HS256')

# Decode
decoded = jwt.decode(token, secret, algorithms=['HS256'])

Java

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.Claims;

// Encode
String token = Jwts.builder()
    .setSubject("1234567890")
    .claim("name", "John Doe")
    .signWith(SignatureAlgorithm.HS256, "your-secret-key".getBytes())
    .compact();

// Decode
Claims claims = Jwts.parser()
    .setSigningKey("your-secret-key".getBytes())
    .parseClaimsJws(token)
    .getBody();

Frequently Asked Questions about JWTs

1. Where should I store JWTs on the client-side? Store JWTs in an HttpOnly cookie to prevent XSS attacks. Avoid localStorage or sessionStorage as they are vulnerable to script access.

2. How do I handle JWT expiration and token renewal? Implement a refresh token mechanism. When the access token expires, use a long-lived refresh token to request a new access token without requiring the user to log in again.

3. What is the difference between JWT, JWS, and JWE?

  • JWT is the standard.
  • JWS (JSON Web Signature) is a signed JWT, ensuring integrity.
  • JWE (JSON Web Encryption) is an encrypted JWT, ensuring confidentiality.

4. Is JWT an encryption method? No, a standard JWS is signed, not encrypted. The payload is visible to anyone who intercepts the token. Use JWE if you need to encrypt the payload.

Conclusion

JWTs offer a powerful and flexible solution for authentication and information exchange in modern applications. By understanding their structure, flow, and security considerations, you can build secure, scalable, and stateless systems.