Cookies, Sessions, and State
Table of Contents
- HTTP Has No Memory
- Cookies: A Note the Browser Carries
- How a Login Works
- Cookie Settings That Matter
- Sessions vs. Tokens
- localStorage: Memory Only the Browser Uses
- Third-Party Cookies and Tracking
- Try It Yourself
1. HTTP Has No Memory
Here's a fact that surprises most people: HTTP is stateless. Every request is handled on its own, as if the server had never seen you before. The server doesn't remember that you loaded the home page a second ago, or that you logged in, or what's in your cart.
That was a deliberate design choice, and a good one. A server that doesn't have to remember anything between requests is simple, and it's easy to run many copies of it side by side — any copy can answer any request.
But real websites obviously do remember you. You log in once and stay logged in. Your cart survives from page to page. Your language choice sticks. So where does that memory come from?
The answer: the client carries it. With every request, the browser sends a small reminder of who you are. That reminder is a cookie.
2. Cookies: A Note the Browser Carries
A cookie is a small piece of text that a server asks the browser to keep and send back. It works with two headers.
The server sets one in a response, with Set-Cookie:
HTTP/1.1 200 OK
Set-Cookie: lang=km
The browser saves it, labelled with the site it came from. From then
on, every request to that same site carries it automatically, in a
Cookie header:
GET /products HTTP/1.1
Host: shop.example.com
Cookie: lang=km
The server reads it and answers in Khmer. It still doesn't remember you — you reminded it.
A few things to notice:
- The browser does this automatically. Your code doesn't have to attach cookies; they just go along with every request to that site.
- Cookies belong to a site. A cookie from
shop.example.comis never sent togoogle.com. - They're small — about 4 KB each at most — so they're for short values, not data.
3. How a Login Works
Logging in is the most important use of cookies. Here's the classic flow:
Browser Server
│ POST /login │
│ email=dara@…&password=… ────────────▶ │ checks the password,
│ │ creates session "a8f3…"
│ │ and remembers: a8f3… = Dara
│ ◀──────────── 302 Found │
│ Location: /dashboard │
│ Set-Cookie: session=a8f3…│
│ │
│ GET /dashboard │
│ Cookie: session=a8f3… ─────────────▶ │ looks up a8f3… → Dara
│ ◀──────────── 200 OK, "Hi Dara!" │
- You send your email and password once, with a POST.
- The server checks them. If they're right, it creates a session: a long, random ID — impossible to guess — and stores a note in its database or memory saying "this ID belongs to Dara".
- It sends the ID back in
Set-Cookie, and redirects you. - Every request after that carries the session cookie. The server looks up the ID and knows it's you. Your password is never sent again.
- When you log out, the server deletes the session, and the ID becomes worthless.
This means the session cookie is, in effect, you. Anyone who gets a copy of it can use the site as you, without your password. Protecting it is what the next section is about.
4. Cookie Settings That Matter
A Set-Cookie header can carry extra settings after the value:
Set-Cookie: session=a8f3…; Max-Age=604800; Path=/; Secure; HttpOnly; SameSite=Lax
| Setting | What it does |
|---|---|
Max-Age / Expires | How long to keep it. Without one, it's deleted when the browser closes |
Path / Domain | Which URLs it's sent to |
Secure | Only send it over HTTPS, never plain HTTP |
HttpOnly | JavaScript on the page can't read it — only the browser sends it |
SameSite | Whether to send it when another site makes the request |
The last three are security settings, and a login cookie should have all of them:
Secure— because, as chapter 4 showed, anything sent over plain HTTP can be read on the way.HttpOnly— so that if an attacker manages to run their own JavaScript on the page, it still can't read your session and send it to them.SameSite=Lax(the default in modern browsers) — so that if another website secretly sends a request to your bank, your bank cookie doesn't go along with it. This blocks an attack called CSRF — cross-site request forgery.
You'll learn these attacks properly on the Cybersecurity track. For
now: cookies that prove who someone is must be Secure, HttpOnly,
and SameSite.
5. Sessions vs. Tokens
The session approach keeps the important information on the server: the cookie is just an ID that points to it. There's a second common approach, where the client carries a token that contains the information itself, signed by the server so it can't be faked.
| Session cookie | Token (e.g. JWT) | |
|---|---|---|
| What the client holds | A random ID | Signed data: who you are, until when |
| Where the truth lives | The server's session store | Inside the token |
| How it's sent | Cookie header, automatically | Usually Authorization: Bearer …, by your code |
| Common in | Traditional websites | APIs, mobile apps, single sign-on |
The Keycloak Crash Course on this site is built on tokens — a
JWT sent in the Authorization header — and its "Understanding the
JWT" chapter shows what's inside one. Both approaches solve the same
problem: reminding a stateless server who you are, on every request.
6. localStorage: Memory Only the Browser Uses
Browsers also give JavaScript a place to store data for a site:
localStorage. It's a simple list of keys and values:
localStorage.setItem("theme", "dark");
localStorage.getItem("theme"); // "dark"
The big difference from cookies: localStorage is never sent to the server. It stays in the browser, and only the page's JavaScript can read it. It also holds much more — a few megabytes per site.
That makes it good for things only the browser cares about: preferences, a draft you haven't sent yet, which tab was open. This very website uses it to remember whether you chose light or dark mode — there's no server to remember it for you.
What it's not good for is secrets. Any JavaScript on the page can
read it, so it doesn't have the protection of an HttpOnly cookie.
(sessionStorage works the same way, but forgets everything when you
close the tab.)
7. Third-Party Cookies and Tracking
A page can load things from other sites: an ad, a "Like" button, an analytics script, an embedded video. Those requests go to the other site's server — and they can set and receive that site's cookies. These are called third-party cookies.
Here's the problem. Imagine an ad company whose ads appear on a news site, a shopping site, and a travel site. Every time you visit any of them, your browser sends a request to the ad company, with the same ad company cookie. Now the ad company can build a list of every site you visited — without you ever visiting the ad company itself.
That's why:
- Browsers like Safari and Firefox block third-party cookies by default, and Chrome lets you block them too.
- Many countries now have privacy laws, and many sites show those cookie banners asking for consent before setting non-essential cookies.
Cookies that make a site work — your login, your cart — are called essential. When a banner gives you the choice, rejecting the rest won't break the site.
8. Try It Yourself
-
Look at your cookies. Log in to a site you use, open DevTools, and go to Application → Cookies (Chrome/Edge) or Storage → Cookies (Firefox). Find a cookie with HttpOnly and Secure ticked. Its name often includes
session,sid, orauth. Don't copy it anywhere — remember, it's you. -
Watch a cookie get set. Run these with
curl.-csaves cookies to a file, and-bsends them back:curl -c cookies.txt "https://httpbin.org/cookies/set?lang=km" cat cookies.txt curl -b cookies.txt https://httpbin.org/cookies rm cookies.txtThe second
curlsends aCookieheader, and httpbin shows it back to you. That's the browser's whole cookie job, done by hand. -
Find a Set-Cookie header. In the Network tab, reload a big site and click the first request. Look under Response Headers for
set-cookie. What settings does it use? -
Check this site's memory. On this website, open Application → Local Storage and switch between light and dark mode. Watch the
themevalue change.
You now know how the web remembers you. Next, how it avoids downloading the same thing twice — the secret behind fast websites.
Buy Me a Coffee
Found this tutorial helpful? Consider buying me a coffee to support more free content!