Educational Article

What Is a JSON Web Token? A JSON Web Token, usually shortened to JWT, is a compact way to securely represent information between two parties, most c...

whatjsonwebtoken?

What Is a JSON Web Token?


A JSON Web Token, usually shortened to JWT, is a compact way to securely represent information between two parties, most commonly a client and a server. If you have ever logged into a web app and stayed signed in while making API requests, there is a good chance a JWT was involved.


In this article, you’ll learn what a JSON Web Token is, how it works, what it contains, where developers use it, and what security mistakes to avoid when implementing JWT-based authentication.


What Is a JSON Web Token?

Free Tool

JSON Formatter

Format, validate, and beautify JSON with syntax highlighting

Try it free

A JSON Web Token is a string that contains JSON data, digitally signed so that the receiver can verify it has not been changed. JWTs are commonly used for authentication and authorization in web applications, mobile apps, and APIs.


A JWT usually looks like this:


textCODE
xxxxx.yyyyy.zzzzz

Those three parts are separated by dots. Each part is Base64URL-encoded, meaning it is safe to send inside URLs, HTTP headers, and API requests.


A typical JWT represents claims such as:


  • Who the user is
  • When the token was issued
  • When the token expires
  • What permissions or roles the user has
  • Which application or service issued the token

  • For example, after a user logs in, a server might issue a JWT saying: “This user is user_123, they are authenticated, and this token expires in 15 minutes.” The client can then include that token in future API requests instead of sending the username and password again.


    How a JWT Is Structured


    A JSON Web Token has three main parts:


    textCODE
    header.payload.signature

    Each part has a specific role.


    Header


    The header describes metadata about the token, usually the token type and the signing algorithm.


    Example header:


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

    Here:


  • alg means algorithm, such as HS256 or RS256
  • typ means token type, usually JWT

  • The algorithm tells the receiving system how the token was signed and how it should be verified.


    Payload


    The payload contains the claims. Claims are pieces of information about the subject of the token.


    Example payload:


    jsonCODE
    {
      "sub": "user_123",
      "role": "admin",
      "exp": 1735689600
    }

    Common JWT claims include:


  • sub: Subject, usually the user ID
  • iss: Issuer, the system that created the token
  • aud: Audience, the intended recipient of the token
  • iat: Issued at time
  • exp: Expiration time
  • nbf: Not before time

  • You can also include custom claims, such as role, plan, or tenant_id. However, you should avoid putting sensitive information in the payload because JWT payloads are encoded, not encrypted.


    If you want to inspect a JWT while debugging, a tool like the JWT Decoder can help you view the header and payload in a readable format. Just remember: decoding is not the same as verifying. A decoded JWT may still be fake or tampered with unless the signature is checked.


    Signature


    The signature is what protects the token from being modified.


    The signature is created using:


    1. The encoded header

    2. The encoded payload

    3. A secret key or private key

    4. The algorithm listed in the header


    Conceptually, it works like this:


    textCODE
    sign(base64url(header) + "." + base64url(payload), secret)

    When the server receives the JWT, it recalculates the signature. If the recalculated signature matches the signature in the token, the server knows the header and payload have not been changed.


    This does not mean the payload is hidden. It means the payload is protected against tampering.


    How JWT Authentication Works


    JWTs are often used in stateless authentication systems. “Stateless” means the server does not need to store a session record for every logged-in user. Instead, the token itself carries enough information for the server to identify and authorize the request.


    A common login flow looks like this:


    1. The user submits their username and password.

    2. The server validates the credentials.

    3. The server creates a JWT with user-related claims.

    4. The server signs the JWT.

    5. The client stores the JWT.

    6. The client sends the JWT with future API requests.

    7. The server verifies the JWT signature and reads the claims.

    8. If the token is valid and not expired, the request is allowed.


    Most APIs expect JWTs in the Authorization header:


    httpCODE
    Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

    The word Bearer means “whoever holds this token can use it.” That is why protecting JWTs is extremely important. If an attacker steals a valid JWT, they may be able to access the API as that user until the token expires or is revoked.


    Example: Protecting an API Route


    Here is a simplified Node.js-style example showing how a server might verify a token:


    jsCODE
    const jwt = require("jsonwebtoken");
    
    const token = req.headers.authorization?.split(" ")[1];
    const user = jwt.verify(token, process.env.JWT_SECRET);
    
    req.user = user;

    In a real application, you would also handle missing tokens, expired tokens, invalid signatures, and authorization checks. Verification should always happen on protected server-side routes, not just in frontend code.


    JWT vs Sessions: What’s the Difference?


    Traditional session-based authentication usually works like this:


  • The user logs in.
  • The server creates a session record in a database or memory store.
  • The server sends the browser a session cookie.
  • On each request, the server looks up the session ID.

  • JWT authentication often works differently:


  • The user logs in.
  • The server creates a signed token containing claims.
  • The client sends the token with each request.
  • The server verifies the token without necessarily checking a session database.

  • Advantages of JWTs


    JWTs can be useful because they are:


  • Portable: They work across web apps, mobile apps, and APIs.
  • Stateless: Servers can verify tokens without storing session state.
  • Compact: They are small enough to send in HTTP headers.
  • Interoperable: JWT is a widely supported standard across languages and frameworks.
  • Useful for distributed systems: Multiple services can verify the same token if they share the correct key or public key.

  • Trade-Offs of JWTs


    JWTs also come with important trade-offs:


  • Revocation is harder: Once issued, a JWT remains valid until it expires unless you add a blocklist or token versioning.
  • Token theft is serious: A stolen bearer token can be used by an attacker.
  • Payload size matters: Large JWTs increase request size.
  • Claims can become stale: If a user’s role changes, old tokens may still contain the previous role until they expire.
  • Implementation mistakes are common: Weak secrets, missing expiration, and improper validation can create security issues.

  • JWTs are powerful, but they are not automatically better than server-side sessions. The right choice depends on your architecture, risk model, and operational needs.


    Common Use Cases for JSON Web Tokens


    JWTs are used in many modern software systems. The most common use cases involve authentication, authorization, and secure exchange of claims.


    API Authentication


    Single-page applications and mobile apps often use JWTs to authenticate API requests. After login, the client receives an access token and sends it to the backend with each request.


    For example:


    httpCODE
    GET /api/profile
    Authorization: Bearer <access_token>

    The API verifies the token, reads the user ID from the sub claim, and returns that user’s profile data.


    Authorization Between Microservices


    In a microservices architecture, one service may need to call another service on behalf of a user. JWTs can carry identity and permission claims across services.


    For instance, an API gateway might validate a JWT from the user and then forward selected claims to internal services. Alternatively, internal services may verify the token themselves using a shared public key.


    Single Sign-On


    JWTs are often used with OAuth 2.0 and OpenID Connect. In these systems, an identity provider issues tokens that applications can use to authenticate users.


    OpenID Connect uses an ID token, which is a JWT containing information about the authenticated user. APIs often use access tokens, which may also be JWTs depending on the provider.


    Temporary Access Links


    JWTs can be used to create time-limited access for specific actions, such as:


  • Password reset links
  • Email verification links
  • File download permissions
  • Invitation links
  • Short-lived admin actions

  • For these cases, the JWT should have a short expiration time and should include only the claims needed to complete the action.


    Important Security Best Practices


    JWT security depends heavily on correct implementation. The format itself is well-defined, but developers must still make careful decisions about storage, validation, expiration, and signing.


    Always Verify the Signature


    Never trust a JWT just because you can decode it. Anyone can create a token-like string with a fake payload. Your backend must verify the signature using the expected algorithm and key.


    A common beginner mistake is to decode the payload and use it directly:


    jsCODE
    const payload = jwt.decode(token); // Not enough for authentication

    Decoding only reads the data. Verification proves that the data was signed by a trusted party and has not been altered.


    Use Strong Secrets or Asymmetric Keys


    If you use HS256, the same secret is used to sign and verify the token. That secret must be long, random, and protected.


    If you use RS256 or ES256, the token is signed with a private key and verified with a public key. This is often better for larger systems because services can verify tokens without having access to the private signing key.


    Set Short Expiration Times


    Every JWT should include an exp claim. Access tokens should usually be short-lived, often minutes rather than days.


    A common approach is:


  • Short-lived access token
  • Longer-lived refresh token
  • Refresh token rotation
  • Server-side revocation for refresh tokens

  • This limits damage if an access token is stolen.


    Do Not Store Sensitive Data in the Payload


    JWT payloads are Base64URL-encoded, not encrypted. Anyone who has the token can decode and read the header and payload.


    Avoid storing:


  • Passwords
  • API keys
  • Credit card data
  • Personal identification numbers
  • Sensitive internal notes
  • Secrets of any kind

  • If you need to inspect or format JSON claims while developing, a JSON Formatter can make the payload easier to read. But remember that readable JSON inside a token should not contain anything you would be uncomfortable exposing to the token holder.


    Validate Claims, Not Just Signatures


    Signature verification is necessary, but not sufficient. Your application should also validate important claims such as:


  • exp: Is the token expired?
  • iss: Was it issued by a trusted issuer?
  • aud: Was it intended for this API?
  • nbf: Is it valid yet?
  • sub: Is the subject valid in your system?

  • Skipping these checks can allow tokens issued for one service or environment to be misused somewhere else.


    JWTs and JSON in Practice


    JWTs are based on JSON, which makes them easy to understand and widely compatible. The header and payload are JSON objects before they are encoded.


    For example, an authentication service might generate a payload like:


    jsonCODE
    {
      "sub": "42",
      "email": "dev@example.com",
      "scope": "read:projects",
      "exp": 1735689600
    }

    That JSON is then encoded into the middle part of the JWT. Because JWTs rely on JSON, developers often need to inspect, format, validate, or transform JSON while working with authentication systems. If you are comparing token claims with API responses or configuration files, the JSON Formatter is useful for quickly validating structure and spotting mistakes.


    In some integration-heavy systems, teams may need to convert JSON payloads to XML for legacy services or documentation workflows. In that case, a tool like JSON to XML Converter can help when you are mapping JWT-related claims or API data into XML-based systems. This is not part of JWT verification itself, but it can be practical when working with older enterprise integrations.


    Common Mistakes Developers Make with JWTs


    JWTs are simple to use at a basic level, but they are also easy to misuse. Here are some mistakes to watch for.


    Treating JWTs as Encrypted Data


    JWTs are usually signed, not encrypted. A signed JWT protects integrity, not confidentiality. If someone has the token, they can decode the header and payload.


    If you need confidentiality, you may need encrypted tokens, secure server-side storage, or a different design.


    Using Long-Lived Access Tokens


    A token that lasts for weeks gives attackers a large window if it is stolen. Prefer short-lived access tokens and a secure refresh strategy.


    Ignoring Key Rotation


    Signing keys should not live forever. Production systems should have a plan for rotating keys safely. With asymmetric algorithms, this is often handled using a JSON Web Key Set, or JWKS, where verifiers can fetch current public keys.


    Storing Tokens Unsafely


    Where you store JWTs matters. Browser storage options have different risks:


  • localStorage is easy to use but vulnerable if your app has cross-site scripting issues.
  • Cookies can be safer against JavaScript access if marked HttpOnly, but require CSRF protection depending on your setup.
  • In-memory storage reduces persistence but may require re-authentication after refresh.

  • There is no universal perfect storage choice. Choose based on your app’s threat model and apply defense-in-depth protections.


    When Should You Use a JWT?


    Use JWTs when you need a compact, signed, portable token that can be verified by one or more services. They are especially useful for APIs, mobile applications, distributed systems, and identity-provider-based login flows.


    JWTs may be a good fit when:


  • You have multiple backend services that need to trust the same identity claims.
  • You are building an API used by web and mobile clients.
  • You use OAuth 2.0 or OpenID Connect.
  • You want short-lived stateless access tokens.
  • You need a standard token format supported across platforms.

  • JWTs may not be the best fit when:


  • You need immediate logout or revocation for every session.
  • Your application is a simple server-rendered website.
  • You plan to store a lot of data in the token.
  • Your team is not prepared to manage token security correctly.

  • For many traditional web applications, secure server-side sessions are still a strong and simpler choice.


    Frequently Asked Questions


    What does JWT stand for?


    JWT stands for JSON Web Token. It is a standard format for representing claims as a compact, URL-safe string. JWTs are commonly used for authentication and authorization in web applications and APIs.


    Is a JWT encrypted?


    Usually, no. Most JWTs are signed, not encrypted. This means the receiver can verify that the token was not modified, but anyone who has the token can decode and read the header and payload. Do not put secrets or sensitive personal data inside a normal signed JWT.


    What is the difference between decoding and verifying a JWT?


    Decoding a JWT means reading its header and payload. Verifying a JWT means checking its signature and validating claims such as expiration, issuer, and audience. For authentication, decoding alone is not safe; your backend must verify the token.


    Where should I store a JWT in a browser app?


    It depends on your security requirements. localStorage is convenient but exposed to JavaScript, making it risky if cross-site scripting occurs. HttpOnly cookies protect the token from JavaScript access but require careful cookie and CSRF configuration. Many production systems combine short-lived access tokens with secure refresh mechanisms.


    How long should a JWT last?


    Access tokens should usually be short-lived, often between 5 and 30 minutes depending on the application’s risk level. Longer sessions are typically handled with refresh tokens, which should have stronger protections and revocation mechanisms.


    Can a JWT be revoked?


    A JWT cannot be “taken back” automatically once issued if your server only validates the signature and expiration. To revoke JWTs before they expire, you need extra infrastructure such as a token blocklist, short expiration times, refresh token rotation, user token versions, or server-side session tracking.

    Related Tools

    Related Articles