Imagine your web application is a party, and you need a way to ensure only the right guests get in. That’s where JSON Web Tokens (JWT) come in—they act like VIP passes, ensuring that only authorized guests (users) gain access!
What is JWT?
JWT stands for JSON Web Token. It’s a compact, secure way to transmit information between two parties. Think of it as a special code that proves someone is who they claim to be and guarantees that the information hasn’t been tampered with.
We previously discussed why basic authentication isn’t the safest option. For a quick refresher, check out my previous post.
JWT Breakdown: What’s Inside?
Let’s break down the three main parts of a JWT:
Image credit: Michał Sajdak
1. Header
The header typically consists of two parts:
-
alg
: The algorithm used to sign the token, such as HMAC SHA256 (HS256
). -
typ
: The type of token, which is usuallyJWT
.
Example:
{
"alg": "HS256",
"typ": "JWT"
}
2. Payload
The payload contains the claims or statements about an entity (usually the user) and any additional data. Common claims include:
-
sub
: Subject of the token (usually a unique identifier for the user). -
name
: Name of the user. -
iat
: Issued At, indicating when the token was issued.
Example:
{
"sub": "1234567890",
"name": "Priya",
"iat": 1516239022
}
3. Signature
The Signature is like a secret stamp that ensures the token’s legitimacy. It’s used to verify that the sender of the JWT is who it claims to be and that the message hasn't been tampered with. It’s created by encoding the header and payload, then signing them with a secret key.
Example:
HMACSHA256(
BASE64URL(header) + "." + BASE64URL(payload),
secret
)
BASE64URL
- Base64URL encoding is a variant of Base64 encoding designed to be URL-safe. It is used in JWTs to ensure that the encoded data is safe for inclusion in URLs.
JWT Representation: The Three Parts
When you put it all together, a JWT looks like this:
- Header (blue) comes first.
- Payload (green) is second.
- Signature (red) is last.
Each section is encoded and concatenated with dots to form the complete JWT. This structure ensures each part can be easily identified and processed.
Signing Algorithms: Symmetric vs. Asymmetric
Image credit: ByteByteGo
1. Public Key / Asymmetric
Asymmetric signing uses a pair of keys: a private key to sign the JWT and a public key to verify it. Common asymmetric algorithms include RS256
(RSA).
How It Works:
- Two Keys: The private key signs the JWT, while the public key is used for verification.
- Separation of Responsibilities: Only the server holding the private key can sign tokens, and anyone with the public key can verify them.
- Enhanced Security: Since the signing key (private key) is kept secret and verification uses the public key, it’s harder for attackers to forge tokens.
2. Symmetric
In symmetric signing, the same secret key is used for both signing and verifying the JWT. The most commonly used symmetric algorithm is HMAC SHA256
(HS256).
How It Works:
- Single Key: Both the server generating the JWT and the server verifying it use the same key.
- Simplicity: This method is easy to set up, involving just one secret key that must be securely shared and stored.
Which One to Choose?
- Symmetric: Best suited for scenarios where both signing and verification occur within a trusted environment.
- Asymmetric: Ideal for distributed systems where multiple services need to verify tokens, but only the authorization server should sign them. This is commonly used for public APIs and microservices architecture that involve third-party verification.
How is a JWT Created?
Here’s how JWTs are typically created:
1. User Logs In
The user sends their login credentials (username and password) to the server via a POST request.
Example:
POST /login
Content-Type: application/json
{
"username": "priya",
"password": "yourPassword"
}
2. Server Authenticates the User
The server checks the provided credentials against stored data (typically in a database). If valid, the user is authenticated.
3. Create the JWT
The server creates the JWT by:
- Creating the Header: Define the algorithm and token type.
- Creating the Payload: Add user information.
- Signing the JWT: Combine and sign the header and payload with a key.
4. Send the JWT to the User
The server sends the JWT back to the client as part of the HTTP response. The client typically stores this token in localStorage, sessionStorage, or a secure HTTP-only cookie.
Example:
HTTP/1.1 200 OK
Content-Type: application/json
{
"token": "<your_jwt_token>"
}
5. Client Uses the JWT for Subsequent Requests
For protected endpoints, the client includes the JWT in the Authorization header.
Example:
GET /protected-endpoint
Authorization: Bearer <your_jwt_token>
How is a JWT Verified?
JWT verification involves checking the token's validity and ensuring the payload hasn’t been tampered with. Here’s how:
1. Server Receives and Decodes the JWT
- Decode the Header and Payload to understand the token’s content.
- The Signature is verified but not decoded directly.
2. Verify the Signature
- Reconstruct the data from the Header and Payload:
base64UrlEncode(header) + "." + base64UrlEncode(payload)
. - Apply the same hashing algorithm specified in the Header using the secret key (for
HS256
) or the public key (forRS256
). - Compare the newly generated signature with the one included in the JWT. If they match, the token is valid and untampered.
3. Validate Claims
-
Expiration (
exp
): Check if the token has expired by comparing theexp
claim with the current time. -
Subject (
sub
): Ensure the subject claim matches the intended user or entity.
4. Use the Payload Data
- If the token is valid, the payload can be used to authenticate the user or perform authorized actions.
5. Handle Verification Failures
- If any checks fail (e.g., signature mismatch, expiration), reject the token and return an appropriate error (e.g.,
401 Unauthorized
).
Wrapping Up
JWTs provide a secure way to protect your web apps, whether you choose symmetric or asymmetric methods. In the next blog, we’ll explore how to integrate JWTs with Spring Security for even more robust protection.
Want to Learn More?
🛠 Play with JWTs and see how they work.
🕵️♀️ Hacksplaining helps you understand security better.
Stay tuned for our next post on using JWTs with Spring Security!
Top comments (0)