Skip to main content
Bytes & Beyond

JWT Tokens

Understanding JSON Web Tokens - structure, encoding, signature verification, and authentication flow

A token is a secure, temporary piece of data that represents a user identity or permissions. It allows access to protected resources without repeatedly sending sensitive credentials.

What is JWT?

JWT (JSON Web Token) is a compact, self-contained token used for authentication and authorization between a client and a server.

Key Properties:

  • Compact: Small and lightweight, efficient for HTTP headers
  • Self-Contained: Carries all necessary user information (claims), allowing the server to verify the user without a database lookup
  • Stateless: The server does not need to store session state

JWT Structure

Header.Payload.Signature

Example:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4iLCJpYXQiOjE1MTYyMzkwMjJ9.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT STRUCTURE

Contains metadata about how to process the token.

{
    "alg": "HS256",//Algorithm used for signing (e.g., HS256, RS256)
    "typ": "JWT"//Token type, always "JWT".
}

Base64Url Encoded Header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Payload

Contains claims - statements about the user and the token.

{
    "sub": "1234567890",
    "iat": 1516239022,
    "exp": 1516325422,
    "role": "admin",
    "email": "user@example.com"
}

Standard Claims:

  • sub (Subject): User ID
  • iss (Issuer): Who created it
  • aud (Audience): Who it is for
  • iat (Issued At): Creation time
  • exp (Expiration): When it expires

Base64Url Encoded Payload: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4iLCJpYXQiOjE1MTYyMzkwMjJ9

Signature

Ensures the token hasn’t been tampered with. Created by hashing the encoded Header and Payload with a secret key.

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

The signature provides:

  • Integrity: Proves the data hasn’t been modified (hash of modified data won’t match)
  • Authenticity: Proves it was created by a trusted source (only the source knows the secret key)

Why Base64URL Encoding?

JWT uses Base64URL encoding for the header and payload (not encryption):

  • Portability: Ensures the token uses only ASCII-safe characters, preventing corruption in HTTP headers, cookies, or across different platforms
  • Determinism: Hashing requires the exact same byte sequence every time. Encoding provides a consistent string so different systems can reliably verify the signature
  • URL-Safe: Base64URL replaces + with - and / with _, making it safe for URLs and query strings

Note: Security comes from the signature, not from hiding data. An attacker can read the payload but cannot forge a valid token without the secret key.

Why Use JWT Over Sessions?

JWT Benefits

The Authentication Flow

  • Initial Login Request: The user types their username and password into the client (browser or mobile app) and sends a POST request to the server.

    POST /login
    { "username": "admin", "password": "password123" }
  • Creation & Signing (Server Side): The server checks the database. If the password is correct, it generates the JWT by creating the Header and Payload, signing them using its Secret Key and sends the signed JWT back to the client.

  • Storage (Client Side): The browser receives the token. Since the server is stateless (it won’t remember the user), the client must save this token for later use.

    Common storage: HttpOnly Cookies (safest) or localStorage

  • The Protected Request: When the user wants to access protected data (e.g., GET /api/profile), the client attaches the JWT to the request using the Authorization header.

    Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
  • Verification: The server receives the request, extracts the token, verifies the signature, checks the expiration, and if valid, returns the requested data. JWT Authentication Flow

Complete JWT authentication flow.