Sitemap
Keshav Patel

Keshav Patel

Software Engineer at Dassault Systèmes.

From Cookies to JWT: How Authentication Actually Makes Sense

4 min readJan 23, 2026

--

Most tutorials start with JWT.
I had to start with
confusion.

When I first learned authentication, everything felt magical in the worst way.

  • Cookies appeared from nowhere
  • Sessions lived “on the server” (somewhere?)
  • JWTs were called stateless — yet they somehow knew who I was

I could implement authentication, but I didn’t understand it.

So I decided to rewind — not to frameworks, but to the problem authentication was trying to solve.

Step 1: “I just want the user to stay logged in”

You build your first website.

There’s a login form:

  • username
  • password

The user logs in successfully.
Then they click another page.

-> New HTTP request.

HTTP doesn’t remember anything.

So the real question becomes:

How do I know this is the same user?

Step 2: Sessions — the first solution that makes sense

The simplest workable idea is this:

  1. User logs in
  2. Server creates a session
  3. Server sends a session ID back to the browser (via a cookie)
  4. Browser sends that cookie on every request
  5. Server looks up the session → user found → authenticated

The browser stores something like:

session_id=abc123

The server stores everything else:

  • who the user is
  • their roles
  • expiry time

This is called stateful authentication.

The server remembers you.
The browser just carries an ID card.

And honestly — this model is brilliantly simple.

Step 3: “Wait… wasn’t there something even simpler?”

Yes. Basic Authentication.

Every request looks like this:

Authorization: Basic base64(username:password)

No cookies.
No sessions.
No memory.

Just credentials. Every time.

At first, you might think:

“Do users really type their password on every request?”
-
No.

The hidden twist…

Browsers cache the credentials internally and automatically attach them to every request.

So the next time you:

  • CTRL + Click an internal link
  • Open a link in a new tab
  • Refresh the page

…and you’re still authenticated — it starts feeling like a session.

But it isn’t.

There’s no session ID.
No server-side memory.

Your username and password are still being sent on every request.

⚠️ That’s the dangerous part.

This is where an important lesson appears:

Convenience is not the same as security.

Step 3.5: Why everything still feels the same (and why that’s misleading)

At this point, everything still feels like magic.

Whether it’s Basic Auth, sessions, or JWT —
opening a new tab and staying logged in looks exactly the same.

That’s because the browser doesn’t understand authentication.
It only knows how to automatically resend headers.

The difference isn’t visible in behavior.
It lives in what travels with every request, and who controls it.

Press enter or click to view image in full size
An Image showing authentication mechanisms and the headers they send on each request
How different authentication mechanisms identify the user on each request

Same UX.
Completely different security model.

Step 4: Why sessions felt like a huge upgrade

Sessions fixed almost everything Basic Auth got wrong.

Press enter or click to view image in full size

If someone steals your session cookie, they can impersonate you —
but they don’t learn your password.

That’s a massive improvement.

For a long time, sessions were the answer.

Step 5: The problem wasn’t sessions — it was scale

Sessions work perfectly…
until your application grows.

Get Keshav Patel’s stories in your inbox

Join Medium for free to get updates from this writer.

Imagine this:

  • User logs in → Server A creates session
  • Next request goes to Server B
  • Server B has no idea who this user is

Now you need:

  • sticky sessions, or
  • shared session storage (Redis, DB)

More infrastructure.
More complexity.

And eventually, someone asks:

“What if the server didn’t remember users at all?”

That’s the birth of stateless authentication.

Step 6: Stateless auth (the mental shift)

Stateless authentication means:

Every request must prove who you are — by itself.

We already tried this once (Basic Auth), and it failed.

So the new rules became:

  • Don’t resend the password
  • Don’t store user state on the server
  • Still be able to trust the client

This is the exact problem JWT was designed to solve.

Step 7: JWT — not magic, just signed facts

A JWT is not encryption.
It’s tamper-proof data.

Inside a JWT is a JSON payload like:

{
"user": "alpha",
"roles": ["ADMIN"],
"exp": 1700000000
}

The server:

  • Signs it with a secret key
  • Sends it to the client

The client:

  • Sends it back on every request

The server:

  • Verifies the signature
  • Checks expiry
  • Trusts the data

No session lookup.
No shared store.
No memory.

The server doesn’t remember you.
It
trusts what it signed.

Step 8: Is JWT “better” than sessions?

No.

JWT is different, not superior.

Sessions

  • Easy logout
  • Easy revocation
  • Server-controlled
  • Stateful

JWT

  • Scales effortlessly
  • Ideal for APIs & mobile
  • Harder to revoke
  • Stateless

JWT wasn’t created because sessions were bad.

JWT exists because systems stopped living on one machine.

Step 9: The real security truth people skip

A common fear:

“If someone steals my JWT, can they use it?”

Yes — if the client is already compromised.

And that leads to the most important security mindset:

Security is about damage control, not perfection.

That’s why real systems use:

  • short-lived tokens
  • refresh tokens
  • HTTPS
  • revocation strategies

JWT doesn’t remove risk.
It limits the blast radius.

Final takeaway

Authentication didn’t evolve randomly, It evolved because constraints changed:

  1. Basic Auth → too naive
  2. Sessions → great UX, stateful
  3. Scaling → sessions hurt
  4. JWT → stateless trust

Once you see the journey, authentication stops feeling magical.
It becomes… logical.

--

Keshav Patel
Keshav Patel

Written by Keshav Patel

Software Engineer at Dassault Systèmes.