JWT BasicsΒΆ
What is a JWT?ΒΆ
JWT (JSON Web Token) is an open standard (RFC 7519) that defines a compact, URL-safe way to transmit claims (a JSON object) between parties.
In most real-world applications, a βJWT tokenβ is a signed token (a JWS) whose payload follows the JWT claims conventions.
JWTs are commonly used for:
- Web authentication / API auth: clients send a token on each request.
- Information exchange: recipients can verify the data was signed by a trusted issuer.
- Stateless sessions: the token carries session context so the server doesnβt need session storage.
SuperJWT support
SuperJWT currently supports signed JWTs (JWS), not encrypted JWTs (JWE).
Throughout the documentation, βJWTβ refers to a JWT payload embedded in a JWS (compact serialization).
JWT vs JWS vs JWEΒΆ
JWT, JWS, and JWE are related standards:
- JWS (JSON Web Signature) (RFC 7515) defines how to sign data and how the token is serialized.
- JWT (JSON Web Token) (RFC 7519) defines the meaning and common fields of the JSON payload (claims).
- JWE (JSON Web Encryption) (RFC 7516) defines how to encrypt a token. (Not supported by SuperJWT.)
In practice, a signed JWT is a JWS: the JWS βpayloadβ is a JSON object containing JWT claims.
Relationship between JWT and JWS:
βββββββββββββββββββββββββββββββββββββββ
β JWS Token β
β (JSON Web Signature) β
β β
β Header . Payload . Signature β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββ β
β β JWT Claims β β
β β (JSON Web Token Payload) β β
β βββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββ
Simply put:
- JWS provides the signing mechanism and structure
- JWT defines the standard claims and semantics for the payload
- A JWT token is typically a JWS token with JWT-formatted claims
Token StructureΒΆ
Signed JWTs use the JWS compact serialization format:
All three parts are Base64URL-encoded and separated by dots (.).
Example token (line breaks added for readability):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 # (1)
.
eyJzdWIiOiJ1c2VyMTIzIiwiaWF0IjoxNzM0MTM0NDAwfQ # (2)
.
OpOSSw7e485LOP5PrzScxHb7SR6sAOMRckfFwi4rp7o # (3)
-
Header (Base64URL-decoded):
-
Payload (Base64URL-decoded):
-
Signature (binary data encoded as Base64URL).
For a detailed breakdown of header fields and registered claims, see JWT Content.
How JWT/JWS WorksΒΆ
Token Creation (Encode)ΒΆ
graph TB
A["*headers*
(JSON)"] --> B("Base64URL encode()")
C["*payload*
(JSON)"] --> D("Base64URL encode()")
D --> F["*payload*
(bytes)"]
B --> E["*headers*
(bytes)"]
E --> H("Algorithm.sign(
*headers*.*payload*, Key)")
F --> H
G["Key"] --> H
Y["Algorithm"] --> H
H --> I["*signature*
(bytes)"]
I --> J["Final token
*header.payload.signature*
(bytes)"]
F --> J
E --> J
Steps:
- Create the JOSE header (algorithm and token type).
- Create the payload with JWT claims.
- Base64URL encode both the header and the payload.
- Concatenate them with a dot:
encoded_header.encoded_payload. - Sign this string using the algorithm specified in the header.
- Base64URL encode the signature.
- Concatenate all three parts:
header.payload.signature.
Token Verification (Decode)ΒΆ
graph TD
A[*header.payload.signature*] --> B[Split by dots]
B --> C[*header*]
B --> D[*payload*]
B --> E[*signature*]
C --> F["Base64URL decode()"]
D --> G["Base64URL decode()"]
F --> H[Extract Algorithm]
H --> I[Recreate Signature]
G --> I
I --> J[Compare Signatures]
E --> J
J --> K{Match?}
K -->|Yes| L[Valid Token]
K -->|No| M[Invalid - Tampered!]
Steps:
- Split the token by dots (
.) into three parts. - Base64URL decode the header and payload.
- Extract the algorithm from the header.
- Recreate the signature using:
- The decoded header and payload.
- The same secret or public key.
- The algorithm from the header.
- Compare the recreated signature with the provided signature.
- If they match β the token is valid and genuine.
- If they don't match β the token is invalid or tampered with.
Security ModelΒΆ
What JWT/JWS providesΒΆ
- Integrity: detects if the token has been tampered with.
- Authentication: verifies the token was created by someone with the correct key.
- Non-repudiation: the issuer cannot deny signing (when using asymmetric keys).
What JWT/JWS does not provideΒΆ
- Confidentiality: the payload is only Base64URL-encoded, not encrypted.
- Privacy: anyone can decode and read the payload.
Important Security Note
JWT tokens are signed, not encrypted. The payload is only Base64URL-encoded, which means anyone can decode and read it. Never store sensitive information like passwords, credit card numbers, or private keys in JWT claims.
If you need encryption, use JWE (JSON Web Encryption) instead, which SuperJWT may support in a future version.
Where to put JWTsΒΆ
Most APIs carry JWTs in the Authorization header:
If you store JWTs in browsers, be deliberate about your threat model:
- HTTP-only cookies reduce exposure to XSS (but you must handle CSRF).
- Web storage (localStorage/sessionStorage) is easier but exposes tokens to XSS.
Base64URL EncodingΒΆ
JWT uses Base64URL encoding (not standard Base64) which is URL-safe:
Differences from standard Base64:
- Replaces
+with- - Replaces
/with_ - Removes padding
=characters
This makes tokens safe to use in:
- URLs (query parameters)
- HTTP headers (Authorization header)
- Cookies
- POST form data
Example:
# Standard Base64
"Hello World!" β "SGVsbG8gV29ybGQh"
# Base64URL (no padding)
"Hello World!" β "SGVsbG8gV29ybGQh"
# With special characters
"data+value/test=" β Standard: "ZGF0YSt2YWx1ZS90ZXN0PQ=="
β Base64URL: "ZGF0YSt2YWx1ZS90ZXN0"
Common Use CasesΒΆ
1. AuthenticationΒΆ
User Login β Server Issues JWT β Client Stores Token β
Client Sends Token with Requests β Server Verifies Token β Access Granted
2. Single Sign-On (SSO)ΒΆ
One JWT token can authenticate across multiple services without additional authentication:
3. Secure Information ExchangeΒΆ
Safely transmit information between parties:
# Party A creates and signs a JWT
token = superjwt.encode(claims={"data": "sensitive_info"}, key=secret_key)
# Party B receives and verifies
claims = superjwt.decode(token, key=secret_key)
# If verification succeeds, Party B knows:
# 1. The token came from someone with the secret key
# 2. The data hasn't been tampered with
When to Use JWTΒΆ
β Use JWT when:
- Building stateless, scalable APIs (see FastAPI Integration).
- Implementing a microservices architecture.
- Sharing authentication across domains.
- Avoiding server-side session storage.
- Building Single Page Applications (SPAs).
- Implementing mobile app authentication.
β Consider alternatives when:
- You need instant token revocation.
- You are storing large amounts of data.
- You require high security for sensitive operations.
- You are managing long-lived sessions.
- You are building traditional server-rendered applications.
Next StepsΒΆ
Now that you understand the basics of JWT and JWS:
- Learn about JWT Content - Standard claims, JOSE headers, and payload structure
- Explore Signing Algorithms - HMAC, RSA, ECDSA, and EdDSA
- Check the Getting Started Guide - Practical usage with SuperJWT
ReferencesΒΆ
- RFC 7519 - JSON Web Token (JWT)
- RFC 7515 - JSON Web Signature (JWS)
- JOSE Working Group - IETF standards body