2.13. Cookies
Table of Contents
Why Cookies Exist
Web servers do not remember you between requests. Every HTTP request is independent. If you refresh a page, the server sees it as a completely new request.
This makes it hard to:
- Keep users logged in
- Remember items in a shopping cart
- Store user preferences such as language or theme
Cookies solve this problem by letting the server store small pieces of data in the browser and get them back with future requests.
A cookie is simply:
A small name/value pair that the browser stores and automatically sends with matching requests.
Example idea:
- Server says: “Browser, please store
user_id=123forexample.com.” - Browser stores it.
- Next time you visit
https://example.com/profile, the browser sendsuser_id=123along with the request.
How Cookies Work
Setting Cookies from the Server
Servers set cookies using the Set-Cookie HTTP response header.
Example HTTP response:
HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: theme=dark
Set-Cookie: session_id=abc123The browser reads these headers and stores two cookies:
| Name | Value |
|---|---|
| theme | dark |
| session_id | abc123 |
On the next request to the same site, the browser will send them in the Cookie request header.
Example HTTP request:
GET /dashboard HTTP/1.1
Host: example.com
Cookie: theme=dark; session_id=abc123
The server can then read theme and session_id and customize the response.
Cookie Format
A single cookie is usually represented as:
name=value
Multiple cookies are separated by ; in the Cookie header:
Cookie: name1=value1; name2=value2; name3=value3
Cookie names and values are simple strings. Values can be URL encoded to store spaces or special characters, for example user=John%20Doe.
Cookie Attributes
Cookies are not only name=value. They include attributes that control how and when the browser sends them.
They are set in Set-Cookie responses like this:
Set-Cookie: session_id=abc123; Path=/; Domain=example.com; HttpOnly; Secure; SameSite=Lax; Expires=Wed, 01 Jan 2025 00:00:00 GMTImportant attributes:
| Attribute | Purpose |
|---|---|
Expires | When the cookie should expire (absolute time) |
Max-Age | How long the cookie lives in seconds |
Domain | Which domain(s) will receive this cookie |
Path | Which path prefix must match for cookie to be sent |
Secure | Only send over HTTPS |
HttpOnly | Not accessible to JavaScript |
SameSite | Restrict cross-site sending of cookies |
Important rule: Cookies are controlled only by the server via Set-Cookie. Browsers automatically store and send them according to their attributes. As a backend developer you define exactly how long cookies live and where they can be used.
We will now look at each attribute in more detail.
Session vs Persistent Cookies
Session Cookies
A session cookie exists only while the browser is open. Once the user closes all browser windows for that site, the cookie disappears.
A cookie becomes a session cookie when you do not specify Expires or Max-Age.
Example:
Set-Cookie: session_id=abc123; Path=/; HttpOnly; Secure; SameSite=LaxCharacteristics:
- Good for login sessions that should end when the browser closes
- Saved in memory, not permanent storage
- Disappears when the browsing session ends
Persistent Cookies
A persistent cookie survives browser restarts and is stored on disk. It is created by specifying either:
Expires=DATEabsolute expiration dateMax-Age=SECONDSlifetime from now
Example with Expires:
Set-Cookie: theme=dark; Expires=Wed, 01 Jan 2025 00:00:00 GMT; Path=/
Example with Max-Age:
Set-Cookie: remember_me=true; Max-Age=2592000; Path=/ ; 30 daysApproximate conversions:
| Days | Seconds |
|---|---|
| 1 | 86400 |
| 7 | 604800 |
| 30 | 2592000 |
| 365 | 31536000 |
Rule: Any cookie with Expires or Max-Age is persistent. Any cookie without them is a session cookie.
Use persistent cookies to remember preferences such as theme or language. Use session cookies for temporary state such as login sessions, unless you have a specific reason to persist longer.
Domain and Path Scoping
Cookies are not sent to every website. They are limited by Domain and Path.
Domain Attribute
Domain controls which hostnames receive the cookie.
- If
Domainis not set, the cookie is a host-only cookie. It is sent only to the exact host that set it. - If
Domainis set to.example.com, it can be sent toexample.comand its subdomains likeapi.example.com.
Examples:
Set-Cookie: lang=en; Path=/; Domain=example.comSent to:
https://example.com/https://api.example.com/usershttps://shop.example.com/cart
Not sent to:
https://other.com/
Without Domain:
Set-Cookie: token=abc; Path=/account
Set from api.example.com. It will not be sent to example.com or shop.example.com, only to api.example.com.
Path Attribute
Path is a URL path prefix. The browser sends the cookie only for URLs that start with that path.
Examples:
Set-Cookie: cart_id=123; Path=/shopSent for:
/shop/shop//shop/cart/shop/products/5
Not sent for:
//account/blog/post
Another example:
Set-Cookie: admin_token=xyz; Path=/adminThis helps separate cookies used for admin areas from others.
Rule: The browser sends a cookie only if:
- The request domain matches the cookie
Domain - The request path starts with the cookie
Path - Other security rules such as
SecureandSameSitealso allow it
Secure and HttpOnly Cookies
These two attributes improve security without changing the cookie value itself. They only affect how the browser behaves.
Secure
Secure means the browser will send the cookie only over HTTPS.
Example:
Set-Cookie: session_id=abc123; Path=/; SecureThis cookie will be sent with:
https://example.com/profileyeshttp://example.com/profileno
You should always use Secure for any cookie that has sensitive information such as session IDs, tokens, or user identifiers.
HttpOnly
HttpOnly means JavaScript in the browser cannot read or write this cookie via document.cookie.
Example:
Set-Cookie: session_id=abc123; Path=/; HttpOnly; SecureEffects:
- Cookie is still sent automatically in HTTP requests to the server
- JavaScript cannot access it, which reduces the risk of theft by XSS attacks
Cookie accessibility table:
| Cookie attribute | HTTP requests | JavaScript access |
|---|---|---|
No HttpOnly | Yes | Yes |
With HttpOnly | Yes | No |
Use HttpOnly for session cookies and authentication tokens.
Rule: Authentication cookies should be both Secure and HttpOnly in production. This protects them from network sniffing and JavaScript access.
SameSite and Cross-Site Cookies
SameSite controls when cookies are sent in cross-site requests. This is important for preventing CSRF attacks and for understanding login behavior across different domains.
Common values:
SameSite=StrictSameSite=LaxSameSite=None; Secure
SameSite=Strict
The browser sends the cookie only for requests that originate from the same site.
- User is on
example.com, clicks a link toexample.com/profilecookie sent - User is on
other.com, which loads an image fromexample.com/imagecookie not sent - User is on
other.com, clicks link toexample.comcookie not sent in some cases (depends on browser behavior)
Strict is the safest, but sometimes too strict for normal flows.
SameSite=Lax
This is more relaxed and often the default.
- Cookie is sent on top-level navigation by link from other sites
- Cookie is not sent in most background requests such as images, iframes, or form posts from other sites
Example:
Set-Cookie: session_id=abc123; Path=/; HttpOnly; Secure; SameSite=LaxGood default for normal login sessions that do not need complex cross-site behavior.
SameSite=None; Secure
This allows the cookie to be sent in cross-site requests such as:
- Third party iframes
- Cross-site API calls
- Single sign-on across domains
But, to use SameSite=None, browsers require Secure.
Set-Cookie: sso_token=xyz; Path=/; SameSite=None; SecureUse this when you intentionally need cross-site cookies, for example single sign-on systems.
Rule: If you set SameSite=None, you must also set Secure. Otherwise, many browsers will ignore the cookie.
Reading and Using Cookies in Backend Code
As a backend developer, you usually:
- Read cookies from the incoming request
- Use them to identify or customize the user
- Set or update cookies in the response
The exact code depends on your framework, but the ideas are the same.
Example in Python with a Simple Framework (Conceptual)
Imagine a minimal Python backend:
def handle_request(request):
# Reading cookies from the request
cookies = request.cookies # e.g. {"theme": "dark", "session_id": "abc123"}
theme = cookies.get("theme", "light")
# Use cookie value in logic
if theme == "dark":
body = "<body class='dark'>Welcome</body>"
else:
body = "<body>Welcome</body>"
# Creating a response and setting a cookie
response = Response(body=body, status=200)
response.set_cookie(
key="last_visit",
value="2026-08-27",
max_age=86400,
path="/",
httponly=False,
secure=True,
samesite="Lax",
)
return responseBreakdown:
request.cookiescontains a dictionary of existing cookies- Business logic uses
themeto customize the page response.set_cookieadds aSet-Cookieheader to the HTTP response
Resulting response header might be:
Set-Cookie: last_visit=2026-08-27; Max-Age=86400; Path=/; Secure; SameSite=LaxRaw HTTP Example
You can also think in plain HTTP:
- First request, no cookie yet:
GET / HTTP/1.1
Host: example.comServer responds:
HTTP/1.1 200 OK
Set-Cookie: theme=dark; Path=/; Max-Age=31536000
Content-Type: text/html
<html>...</html>- Second request, browser includes the cookie:
GET /profile HTTP/1.1
Host: example.com
Cookie: theme=dark
Server reads theme and sends a dark themed page.
Common Uses of Cookies
Cookies by themselves are just small key-value storage. How you use them defines their purpose.
Session Management
The most important use for backend developers.
Typical pattern:
- User logs in with username and password
- Server validates credentials
- Server creates a session record in the database
Example table:
| session_id | user_id | created_at | expires_at |
|-----------|---------|----------------------|----------------------|
| abc123 | 42 | 2026-08-27 10:00:00 | 2026-08-27 18:00:00 |
- Server sets cookie:
Set-Cookie: session_id=abc123; Path=/; HttpOnly; Secure; SameSite=Lax- On every next request:
- Browser sends
Cookie: session_id=abc123 - Server looks up
session_idin the session table - Finds
user_id=42 - Treats the request as authenticated as user 42
You never store the password or full user data in the cookie, only a random session ID.
Remembering Preferences
Examples:
- Theme:
theme=dark - Language:
lang=en - Layout options
Cookies for preferences:
- Often persistent with long
Max-AgeorExpires - Not sensitive, so
HttpOnlyis not always required SameSite=LaxorSameSite=Strictis usually fine
Example:
Set-Cookie: lang=en; Max-Age=31536000; Path=/; SameSite=StrictTracking and Analytics
Analytics tools may use cookies to:
- Count unique visitors (
visitor_id=xyz) - Track which pages a user visits
As a backend developer, you should be aware of privacy laws such as GDPR, which may require asking user consent before setting certain cookies.
Cookie Size and Limits
Cookies are not for storing large data. They have limits.
Typical restrictions in browsers:
- Max cookie size: around 4 KB per cookie
- Max number of cookies per domain: around 20 to 50 cookies
- Total cookie size per domain is limited
If you try to store too much data:
- Cookies might get truncated
- Browsers might delete older cookies
- Requests will become larger and slower
Rule: Never store large or sensitive data such as passwords, full profiles, or big JSON blobs in cookies. Store only small identifiers, for example a session ID, and keep the real data on the server.
Performance Impact
Cookies are sent with every request to the matching domain and path. Large cookies mean:
- Bigger HTTP headers
- More bandwidth used
- Slower requests
Good practice: Keep cookies small and limited in number.
Security Considerations
Cookies are heavily related to security. You will learn attacks such as XSS and CSRF in the security section, but here is what relates directly to cookies.
Sensitive Data
Never store these in cookies:
- Passwords
- Credit card numbers
- Personal data that must be protected
Instead, store:
- Random identifiers such as
session_id - Tokens that can be revoked server-side
Use Secure and HttpOnly
For authentication cookies and any cookie that proves identity:
- Add
Secureso they are not sent over HTTP - Add
HttpOnlyso JavaScript cannot read them
Example best practice:
Set-Cookie: session_id=abc123; Path=/; HttpOnly; Secure; SameSite=LaxSameSite and CSRF
SameSite can help reduce Cross-Site Request Forgery attacks:
SameSite=LaxorSameSite=Strictprevents many cross-site scenarios- For APIs, often you use tokens instead of cookies, but the SameSite concept is still important
You will learn more when you study CSRF, but remember that cookies are a big part of that story.
Expiration and Logout
When a user logs out, you should:
- Delete or invalidate the server-side session
- Tell the browser to remove the cookie by setting an expired cookie
Example logout response:
Set-Cookie: session_id=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; Secure; SameSite=Lax
This tells the browser to remove session_id.
Summary
You now know the essentials of cookies from a backend perspective:
- Cookies are small key-value pairs sent via
Set-Cookiein responses andCookiein requests. - They can be session or persistent, controlled by
ExpiresandMax-Age. DomainandPathrestrict where cookies are sent.SecureandHttpOnlyprotect cookies during transport and from JavaScript.SameSitecontrols cross-site behavior and affects security and login flows.- Cookies are widely used for session management, preferences, and sometimes tracking.
- Cookies are limited in size, so you should keep them small and store sensitive or large data on the server instead.
In later chapters about sessions and security, you will build on this knowledge and see exactly how cookies combine with server-side storage to implement robust authentication systems.
Views: 15
KAHIBARO