Skip to main content

JSON Web Tokens (JWT)

JWT is commonly used for authentication and information exchange in web applications.

  • Encodes a JSON object into a compact, URL-safe string that can be easily transmitted between parties.

  • Tamper-Proof — Verify identity and permissions using JWT signature, only trusted party will know secret key.

  • Self-contained — All user permission data is stored in the token without needing repeated database lookups.

  • Reduce Server Load — Replace traditional sessions with a stateless mechanism, removing the need for storage.

Structure of JWT Token

JWT consists of three parts: Header, Payload, and Signature, which are concatenated with periods (.) to form a single string.

A compact, URL-safe string divided into three parts, separated by dots, separately base64 encoded.

  1. Header — Specifies token type and hashing algorithm

    • alg — Defines how the signature is generated, only parties with the correct key can validate the token.
    • typ — Type of token, and not others like JWS and JWE.

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

  2. Payload — Contains claims (statements) about the user and metadata.

    1. Registered — iss, exp, sub
    2. Public — Custom data like role
    3. Private — Agreed upon between parties

    {
    "sub": "1234567890", // Uniquely identifies the user (e.g., user ID or username).
    "name": "user321", // Human-readable identifier
    "iat": 1516239022, // Issued At: Timestamp when the token was created
    "exp": 1516242622, // Expiration Time: When the token expires
    "role": "admin" // Custom Claim: Defines user permissions for Authorization
    }
  3. Signature — Ensures that token hasn’t been tampered with.

    The combination of (1) the encoded header, (2) encoded payload, and (3) a secret key (or private key for RSA/ECDSA)

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

Caveats

  • Expiration (exp) — Tokens must expire (e.g., 15–30 minutes) to limit risk if stolen.
  • HTTPS Required — Prevents token interception.
  • Not Encrypted — Payload is base64-encoded (not secret), so avoid sensitive data in JWT.

Defenses

  1. Enforce one algorithm (e.g., RS256)

  2. Reject unexpected alg values (e.g., "none", "HS256").

  3. Use asymmetric algorithms (RS256, ES256) for stronger security

  4. Validate alg server-side, never trust the client’s header

  5. Use updated libraries (e.g., jose, PyJWT) with strict algorithm checks

  6. Secure keys - private keys for signing, public keys for verification

  7. Use short expiration times (exp) and HTTPS