CodeOath
← All posts
Auth & Security60 min total · 19 parts

OAuth 2.0 and JWT Explained: How "Login with Google" Actually Works

Contents — Part 9 of 19: What's Actually Inside a JWT
Part 9 of 19 · ~2 min

What's Actually Inside a JWT

A JSON Web Token is a compact, signed way to represent claims (facts) about a user or a grant, made of three base64url-encoded parts separated by dots: header.payload.signature.

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0IiwibmFtZSI6IkFsaWNlIn0.4pZ9...
└──── header ────┘ └──────────── payload ────────────┘ └ signature ┘

Decoded, the header identifies the signing algorithm and token type:

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

And the payload is just JSON claims:

{ "sub": "1234", "name": "Alice", "iat": 1710000000, "exp": 1710003600 }

A handful of claim names are standardized (registered claims) and worth recognizing on sight:

ClaimMeaning
subSubject — the user or entity this token is about
issIssuer — who created and signed this token
audAudience — who this token is intended for
expExpiration time (Unix timestamp) — the token is invalid after this
iatIssued at (Unix timestamp)
nbfNot before — the token isn't valid until this time

Two things people get wrong constantly, and both matter operationally, not just academically:

  • A JWT is signed, not encrypted. Anyone with the token — including a user inspecting their own browser network tab — can base64-decode the header and payload and read every claim in plain text. The signature only proves the payload hasn't been tampered with since the server issued it; it proves nothing about confidentiality. Never put secrets (passwords, credit card numbers, internal-only identifiers) in a JWT payload.
  • exp matters far more than it looks like it should. A JWT can't be "revoked" the way a server-side session record can be deleted — it's cryptographically valid until the moment it expires, full stop, even if the user's account is disabled five minutes after the token was issued. This is exactly why real systems pair a short-lived access token (a JWT, minutes to an hour) with a longer-lived refresh token stored server-side, which can be revoked, and which is used to mint new access tokens without forcing the user to log in again.