The flow will be:
- Authentication foundation
- Session vs JWT
- JWT deep dive
- JWT security
- Access/Refresh tokens
- OAuth2 relationship with JWT
- End-to-end production flow
- PKCE
- Storage strategies
- summary
1. Authentication Fundamentals
Every secure application needs answers to two questions:
Authentication
"Who are you?"
Example:
User enters:
username
password
MFA
System verifies identity.
Result:
User is Bhargav
Authorization
"What are you allowed to do?"
Example:
User:
Bhargav
Permissions:
READ_ORDERS
CREATE_ORDER
DELETE_ORDER
Authentication happens first.
Authorization happens after.
Authentication
|
v
Authorization
2. Traditional Session-Based Authentication (Stateful)
Before JWT, applications commonly used sessions.
Flow
User logs in:
Browser
|
| username/password
|
v
Server
Server creates:
Session ID = abc123
Stores:
Database / Memory
abc123
|
|
User:
Bhargav
Role:
ADMIN
Browser receives:
Cookie:
SESSION_ID=abc123
Every Request
Browser sends:
GET /orders
Cookie:
SESSION_ID=abc123
Server:
Receive Session ID
|
v
Search session storage
|
v
Find user
|
v
Allow request
Problems with Sessions
1. Server maintains state
The server must remember:
Session ID
|
v
User Information
2. Scaling problem
Imagine multiple servers:
Load Balancer
/ \
Server A Server B
User logs in:
Server A
Session stored here
Next request:
Server B
No session found
Solutions:
- Sticky sessions
- Shared session database
3. JWT Authentication (Stateless)
JWT solves this by putting information inside the token.
JWT:
JSON Web Token
It is a compact, signed representation of claims between two parties.
Example:
eyJhbGciOiJIUzI1Ni...
JWT vs Session
Session
Server stores user state:
Server
Session ID
|
v
User Data
JWT
Token contains information:
JWT
Header
+
Payload
+
Signature
Server does not need to store session information.
4. JWT Structure
A JWT has three parts:
HEADER.PAYLOAD.SIGNATURE
Example:
xxxxx.yyyyy.zzzzz
Part 1: Header
Contains metadata.
Example:
{
"alg":"RS256",
"typ":"JWT"
}
Meaning:
JWT uses RSA SHA256 algorithm
Part 2: Payload
Contains claims.
Example:
{
"sub":"12345",
"name":"Bhargav",
"role":"ADMIN",
"exp":1788888888
}
Common claims:
| Claim | Meaning |
|---|---|
| sub | User identifier |
| iss | Token issuer |
| exp | Expiration time |
| iat | Issued time |
| roles | User permissions |
Important
JWT payload is NOT encrypted.
Anyone can decode:
Base64 decode
Therefore never store:
Password
Credit card
Secrets
inside JWT.
Part 3: Signature
Signature proves:
"This token was created by a trusted issuer and was not modified."
Example:
Authorization Server:
Header + Payload
|
v
Private Key
|
v
Signature
Final JWT:
Header.Payload.Signature
5. Public Key and Private Key
JWT commonly uses asymmetric cryptography.
Private Key
Secret.
Only authorization server owns it.
Example:
Okta Private Key
Used for:
Signing JWT
Public Key
Can be shared.
Example:
Spring Boot API
uses:
Okta Public Key
to verify.
Flow:
Okta
Private Key
|
|
v
Sign JWT
Spring Boot
Public Key
|
|
v
Verify JWT
6. How JWT Validation Works
Client sends:
GET /orders
Authorization:
Bearer JWT_TOKEN
Spring Boot receives:
HEADER.PAYLOAD.SIGNATURE
Checks:
1. Signature Validation
Spring calculates:
Verify(
Header + Payload,
Public Key
)
If valid:
Token came from trusted issuer
2. Expiration
Checks:
exp
Example:
{
"exp":1788888888
}
3. Claims
Checks:
Example:
role = ADMIN
Allows:
DELETE /users
7. Stateless Nature of JWT
JWT is called stateless because:
Server does not store:
User Session
Every request contains:
All required information
Example:
Request
+
JWT
=
Enough information
Benefits:
- Easy horizontal scaling
- Works well with microservices
- No central session storage
8. JWT Security Best Practices
Short-lived Access Tokens
Example:
Access Token:
5 minutes
15 minutes
1 hour
Why?
If stolen:
Attacker has limited time
9. Refresh Token
Problem:
If access token expires every 15 minutes:
User must login repeatedly.
Solution:
Refresh token.
Flow:
Access Token
expires
|
v
Refresh Token
|
v
Authorization Server
|
v
New Access Token
Example:
Access Token:
15 minutes
Refresh Token:
days/weeks
10. OAuth2 Relationship With JWT
Important:
OAuth2 does not require JWT.
OAuth2 defines:
How to get access
JWT defines:
How to represent the token
Together:
OAuth2
|
|
v
Access Token
|
|
v
JWT Format
11. OAuth2 Components
Resource Owner
User.
Client
Application requesting access.
Example:
Angular Application
Authorization Server
Creates tokens.
Examples:
Okta
Google
Azure AD
Auth0
Resource Server
API protecting resources.
Example:
Spring Boot API
12. OAuth2 Production Flow
Architecture:
Browser
Angular
Spring Boot API
Okta
Phase 1: Backend Startup
Spring Boot starts.
Configuration:
issuer-uri=https://okta.com/oauth2/default
Spring calls:
GET
/.well-known/openid-configuration
This is a REST API.
Response:
{
"authorization_endpoint":"",
"token_endpoint":"",
"jwks_uri":""
}
Spring learns:
Where are public keys?
How to validate tokens?
Phase 2: User Login
Browser opens:
https://myapp.com
Angular loads.
Angular checks:
Do I have token?
If no:
Redirect:
Browser
|
v
Okta Login Page
Phase 3: User Authentication
User enters:
Username
Password
MFA
Important:
Password goes to:
Okta
Not:
Angular
Spring Boot
Phase 4: Authorization Code
Okta returns:
authorization_code
Example:
callback?code=abc123
Phase 5: Token Exchange
Application calls:
POST /token
Okta returns:
Access Token (JWT)
Refresh Token
Phase 6: API Request
Angular sends:
GET /orders
Authorization:
Bearer JWT
Phase 7: Spring Validation
Spring verifies:
JWT Signature
using
Okta Public Key
If valid:
Request allowed
13. PKCE (Proof Key for Code Exchange)
Used mainly for:
Angular
React
Mobile Apps
because they cannot store:
client_secret
PKCE Memory Rule
Remember:
CREATE
HIDE
PROVE
1. Create
Angular creates:
code_verifier
Example:
ABC123_SECRET
2. Hide
Creates:
SHA256(code_verifier)
Result:
code_challenge
Sends:
code_challenge
to Okta.
Keeps:
code_verifier
secret.
3. Prove
Later sends:
authorization_code
+
code_verifier
Okta checks:
SHA256(verifier)
=
stored challenge
If match:
Issue JWT
14. Implicit Flow (Old)
Old SPA flow:
Browser
|
v
Authorization Server
|
v
JWT Token Directly
|
v
Angular
Problem:
Token exposed to browser.
Risks:
- Browser history
- URL leaks
- XSS attacks
15. Token Storage Options
Local Storage
Example:
localStorage.setItem(
"token",
jwt
)
Pros:
- Simple
- Persistent
Cons:
- Vulnerable to XSS
Session Storage
Removed when tab closes.
Better than local storage but still accessible by JavaScript.
Secure HttpOnly Cookie
Example:
Cookie:
SESSION=abc123
HttpOnly
Secure
SameSite
JavaScript cannot access it.
More secure.
Common with:
Backend For Frontend (BFF)
16. Modern Recommendation
For SPA applications:
Use:
Authorization Code Flow
+
PKCE
Avoid:
Implicit Flow
Summary
JWT
A signed token containing claims that allows stateless authentication and authorization.
Session
Stateful authentication where server stores user session information.
OAuth2
Framework for delegated authorization.
OIDC
Authentication layer built on OAuth2.
Discovery Document
Metadata endpoint that provides OAuth endpoints and public keys.
PKCE
Security mechanism that prevents authorization code theft by proving that the same client started and completed authentication.
Production SPA Flow
Angular
|
| PKCE Login
|
Okta
|
| JWT
|
Spring Boot
|
| Verify Signature
|
Allow Request
Top comments (0)