Introduction
Imagine you arrive at a hotel.
At the reception, you show your ID and prove who you are. The receptionist then gives you a room key card.
You don’t need to show your ID every time you enter your room. Instead, you simply present the key card.
The hotel doesn’t need to ask your name again because the card itself proves that you already authenticated.
JWT (JSON Web Token) works exactly like that.
- Username and password = Your ID
- JWT = Hotel key card
- Server = Receptionist
What is JWT?
JWT stands for JSON Web Token.
It is a compact string that proves a user has already logged in successfully.
Instead of storing login sessions on the server, the server gives the client a signed token.
The client sends this token with every request.
Example:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Enter fullscreen mode Exit fullscreen mode
The server verifies the token and allows access.
Why Do We Need JWT?
Without JWT, every request would require sending the username and password repeatedly.
Browser
|
Username
Password
|
Server
Enter fullscreen mode Exit fullscreen mode
That would be inefficient and insecure.
Instead:
Login once
↓
Receive JWT
↓
Reuse JWT for every request
Enter fullscreen mode Exit fullscreen mode
Stateless Authentication
JWT enables stateless authentication.
Stateful Authentication
Server
|
|-- Session #12345
|-- Session #91821
|-- Session #44211
Enter fullscreen mode Exit fullscreen mode
The server stores every user’s session.
Stateless Authentication (JWT)
Server
(No session storage)
↓
Only verifies token signature
Enter fullscreen mode Exit fullscreen mode
The server doesn’t remember users.
The token remembers.
JWT Structure
A JWT consists of three parts separated by periods.
Header.Payload.Signature
Enter fullscreen mode Exit fullscreen mode
Example
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjMiLCJuYW1lIjoiRXZhbnMiLCJyb2xlIjoiYWRtaW4ifQ
.
K6L6GQX....
Enter fullscreen mode Exit fullscreen mode
Think of it like
Envelope
Letter
Wax Seal
Enter fullscreen mode Exit fullscreen mode
Part 1 — Header
Example
{
"alg": "HS256",
"typ": "JWT"
}
Enter fullscreen mode Exit fullscreen mode
The header tells us:
- Which algorithm signed the token.
- What type of token it is.
Fields:
-
alg→ Signing algorithm -
typ→ JWT
Common algorithms:
- HS256
- RS256
- ES256
Part 2 — Payload
The payload contains claims.
Example:
{
"user_id": 42,
"name": "Evans",
"role": "admin"
}
Enter fullscreen mode Exit fullscreen mode
Think of it as your digital identity card.
Typical information:
- User ID
- Username
- Role
- Permissions
Standard Claims
Claim Meaning sub Subject (User ID) exp Expiration Time iat Issued At iss Issuer aud AudienceExample
{
"sub":"42",
"role":"admin",
"exp":1754440000
}
Enter fullscreen mode Exit fullscreen mode
Important
The payload is NOT encrypted.
Anyone can decode it.
JWT
↓
Base64URL Decode
↓
Payload
Enter fullscreen mode Exit fullscreen mode
Never store:
- Passwords
- PINs
- Secret Keys
- API Keys
- Credit Card Numbers
inside a JWT.
Part 3 — Signature
The signature protects the token from tampering.
The server computes something similar to:
HMACSHA256(
Base64(Header)
+
Base64(Payload),
SecretKey
)
Enter fullscreen mode Exit fullscreen mode
This produces the signature.
The secret key never leaves the server.
Why the Signature Matters
Suppose someone changes:
{
"role":"user"
}
Enter fullscreen mode Exit fullscreen mode
to
{
"role":"admin"
}
Enter fullscreen mode Exit fullscreen mode
The payload changes.
Therefore the signature changes.
Since the attacker doesn’t know the server’s secret key, they cannot generate a valid signature.
Result:
Server
↓
Verify Signature
↓
Invalid
↓
401 Unauthorized
Enter fullscreen mode Exit fullscreen mode
This is why JWTs are tamper-evident.
Login Flow
User
↓
POST /login
↓
Username
Password
↓
Server
Enter fullscreen mode Exit fullscreen mode
Server:
- Checks the database.
- Verifies the password.
- Generates a JWT.
- Returns it.
Example response:
{
"token":"eyJhbGc..."
}
Enter fullscreen mode Exit fullscreen mode
The client stores the token.
Authenticated Request
GET /profile
Authorization: Bearer eyJhbGc...
Enter fullscreen mode Exit fullscreen mode
Server:
- Reads the Authorization header.
- Verifies the signature.
- Checks expiration.
- Extracts the user ID.
- Returns the requested resource.
Complete Request Lifecycle
Client
↓
Login
↓
Receive JWT
↓
Store JWT
↓
Send JWT
↓
Server verifies
↓
Access granted
Enter fullscreen mode Exit fullscreen mode
Where Should Tokens Be Stored?
Browser
Preferred:
- Secure HttpOnly Cookies
- Memory (for SPAs)
Avoid storing long-lived access tokens in localStorage because XSS attacks can expose them.
Mobile
Use secure platform storage:
- iOS Keychain
- Android Keystore
Token Expiration
Example
{
"exp":1754440000
}
Enter fullscreen mode Exit fullscreen mode
Server checks:
Current Time
↓
Expired?
↓
Yes
↓
401 Unauthorized
Enter fullscreen mode Exit fullscreen mode
Expired tokens cannot be used.
Refresh Tokens
Access tokens should have short lifetimes.
Example:
Access Token
15 Minutes
Enter fullscreen mode Exit fullscreen mode
When expired:
Client
↓
Refresh Token
↓
Server
↓
New Access Token
Enter fullscreen mode Exit fullscreen mode
Refresh tokens allow users to remain logged in without entering credentials repeatedly.
JWT vs Sessions
JWT Sessions Stateless Stateful No server-side session storage Server stores sessions Easy to scale More difficult to scale Great for APIs Great for traditional web applications Client sends token Client sends session cookieJWT in a Go (Gin) Backend
Login Endpoint
POST /login
↓
Validate Request
↓
Find User
↓
Compare Password Hash
↓
Generate JWT
↓
Return Token
Enter fullscreen mode Exit fullscreen mode
Protected Route
GET /users
↓
JWT Middleware
↓
Read Authorization Header
↓
Verify Signature
↓
Check Expiration
↓
Extract Claims
↓
Next()
↓
Handler Executes
Enter fullscreen mode Exit fullscreen mode
Middleware Flow
Incoming Request
│
▼
Read Authorization Header
│
▼
Token Present?
│ │
No Yes
│ ▼
401 Verify Signature
│
Valid? │
│ │
No Yes
│ ▼
401 Check Expiration
│
Expired? │
│ │
Yes No
│ ▼
401 Extract Claims
│
▼
Store User in Context
│
▼
Execute Next Handler
Enter fullscreen mode Exit fullscreen mode
Authentication vs Authorization
Authentication answers:
Who are you?
Authorization answers:
What are you allowed to do?
Example:
Login
↓
Authentication
↓
JWT
↓
Authorization
↓
Access Granted
Enter fullscreen mode Exit fullscreen mode
Common Interview Questions
What is JWT?
A signed JSON token used for stateless authentication.
Is JWT encrypted?
No.
It is Base64URL encoded and digitally signed, but not encrypted.
Why can’t users modify the payload?
Because changing the payload invalidates the signature.
What is the purpose of the signature?
To guarantee integrity and authenticity.
Why does JWT expire?
To reduce the damage if a token is stolen.
What is a Refresh Token?
A long-lived credential used to request a new access token after the current one expires.
What happens if the signature is invalid?
The server rejects the request with 401 Unauthorized.
Why is JWT called stateless?
Because the server does not store user sessions.
Every request contains all the information needed to authenticate the user.
Best Practices
- Always use HTTPS.
- Never store passwords inside JWTs.
- Keep access tokens short-lived (10–30 minutes).
- Use refresh tokens for long-lived sessions.
- Store refresh tokens securely.
- Validate the signature on every request.
- Validate the expiration (
exp) claim. - Use strong signing algorithms.
- Rotate signing keys when appropriate.
- Implement token revocation if your application requires immediate logout or compromised-token handling.
Key Takeaways
- JWT stands for JSON Web Token.
- A JWT has three parts:
- Header
- Payload
- Signature
- The payload is readable by anyone who has the token.
- The signature protects against tampering.
- JWT enables stateless authentication.
- Access tokens should expire.
- Refresh tokens provide a secure way to obtain new access tokens.
- JWT authentication is commonly implemented using middleware in Go (Gin), Express.js, Spring Boot, ASP.NET, and many other backend frameworks.
Final Mental Model
Think of JWT like a hotel key card.
User
│
│ Login (Username + Password)
▼
Server verifies credentials
│
▼
Issues a signed JWT
│
▼
Client stores the token
│
▼
Client sends the token with every request
│
▼
Server verifies:
✔ Signature
✔ Expiration
✔ Claims
│
▼
Access Granted
Enter fullscreen mode Exit fullscreen mode
The server does not need to remember the user.
The signed token carries the identity, while the server only needs its secret (or public key, depending on the algorithm) to verify that the token is authentic and has not been altered.
답글 남기기