DEV Community

Juma Evans
Juma Evans

Posted on

JWT Authentication: A Backend Engineer's Mental Model

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
  • Email
  • Role
  • Permissions

Standard Claims

Claim Meaning
sub Subject (User ID)
exp Expiration Time
iat Issued At
iss Issuer
aud Audience

Example

{
    "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:

  1. Checks the database.
  2. Verifies the password.
  3. Generates a JWT.
  4. 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:

  1. Reads the Authorization header.
  2. Verifies the signature.
  3. Checks expiration.
  4. Extracts the user ID.
  5. 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 cookie

JWT 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.

Top comments (0)