Difficulty: Beginner
What is the difference between cookies and sessions? How does login work over stateless HTTP, and what are HttpOnly, Secure and SameSite?
HTTP is stateless: every request is independent, and the server does not remember you from one request to the next. But websites clearly remember who you are, so something has to bridge that gap. Cookies and sessions are the standard answer, and interviewers like to see if you can explain both and how they work together.
A cookie is a small piece of data (up to about 4 KB) that the server asks the browser to store, using a Set-Cookie response header. On every later request to that site, the browser automatically attaches it in the Cookie request header. Cookies live on the client. They can be session cookies (deleted when the browser closes) or persistent (with Expires or Max-Age). They are visible to the user and can be modified by them, so you should never trust sensitive data placed in one unsigned.
A session is server-side state about a user. When you log in, the server creates a session record, storing things like your user id and roles in memory, a database or Redis, keyed by a long random session id. It then sends that id to the browser in a cookie, commonly named JSESSIONID or connect.sid. On each request the browser sends the cookie, the server looks up the session by id and knows who you are. So a session usually uses a cookie as its carrier, but the data stays on the server, and the cookie holds only the opaque identifier. To log out, the server deletes the session record, which immediately revokes access.
Compared with each other: cookies are stored on the client, limited in size, and insecure for sensitive data; sessions are stored on the server, can hold large or sensitive data, and depend on a cookie or URL parameter to link back to the client. The scaling issue with sessions is that if you have multiple servers behind a load balancer, session state must be shared (a central Redis store) or requests pinned to one server (sticky sessions).
The alternative is token-based authentication, typically a JWT, JSON Web Token. The server signs a token containing the user identity and expiry and gives it to the client, which sends it in the Authorization header or a cookie. The server verifies the signature without any lookup, so it scales statelessly. The trade-off is that revoking a token before expiry is hard, so people use short-lived access tokens plus refresh tokens.
Security flags on cookies are a favourite follow-up. HttpOnly stops JavaScript from reading the cookie, blunting XSS theft of session ids. Secure means the cookie is only sent over HTTPS. SameSite (Strict, Lax or None) controls whether the cookie is sent on cross-site requests, and is the main defence against CSRF; Lax is the modern browser default. Domain and Path control scope. Also mention session fixation (always issue a new session id at login), regenerate ids on privilege changes, set sensible expiry, and remember that cookies are sent automatically, which is precisely what makes CSRF possible and why state-changing endpoints need CSRF tokens or SameSite protection. Cookies are distinct from localStorage, which is never sent automatically but is readable by any script on the page.
POST /login HTTP/1.1
Host: app.example.com
Content-Type: application/json
{"email":"a@b.com","password":"***"}
HTTP/1.1 200 OK
Set-Cookie: sid=9f8a3c...; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=86400
GET /profile HTTP/1.1
Host: app.example.com
Cookie: sid=9f8a3c...
The server looks up sid=9f8a3c in its session store to find the user. The browser attaches the cookie automatically.
Cookies, Sessions, Stateless HTTP, JWT, Cookie Flags