Dev Learning Lab

The labs on this site need JavaScript to run. The same content is written out below.

Learn › Networking › HTTP

Cookies

Showing a name tag, every time, to a server that cannot remember you

HTTP does not link one request to the next. The server cannot tell whether an earlier request came from the same browser. So when a login succeeds, the server sends a small value (a cookie) in the response, and the browser stores it and attaches it automatically to every request that goes to the same site.

Partly checked against real execution · Checked with a browser and a test server (deletion when the browser is closed was not verified)

Concepts in this lab

Cookie
A small piece of data that a server sends in a response. The browser stores it and automatically sends it back with every request to the same site. HTTP does not remember state between requests, so this data is used to keep information that must carry over, such as a login state. Because it is stored in the user's browser, you must use it on the assumption that the user can read or change its contents.
HTTP as a stateless protocol
HTTP is a communication protocol in which a client sends a request and a server responds. Stateless means that the server does not remember the content of earlier requests, so each request must carry all the information needed to process it. Because the server keeps no state, any server can take a request, which makes it easy to add servers. Information that must carry over, such as a login state, is kept with cookies, sessions, or tokens.
HttpOnly, Secure, and SameSite
Attributes that protect cookies. HttpOnly stops JavaScript from reading the cookie, which prevents the cookie from being stolen by a script injection attack. Secure makes the browser send the cookie only over HTTPS connections. SameSite restricts sending the cookie with requests that start from another site, which reduces CSRF attacks.
Session
A way to store a user's state on the server side and give the client only an identifier (the session ID) that points to that stored state, delivered in a cookie. The actual information is on the server, so the client cannot change its contents (having the session ID stolen is a different problem). When there are several servers, a common setup keeps this state in a shared store such as Redis so that any server that receives a request can find the same state.

Try these

Running with the default settings

  1. This is the login request. It is the first request, so the browser has no cookie for this site. The server checks the ID and the password in the body.
  2. The server sends Set-Cookie: sid=abc123; Path=/; HttpOnly in the response header. The browser stores this value as a cookie of shop.example. The server writes down on its own side that "abc123 is member 7".
  3. This is the request for shop.example/orders. The browser attached sid to the Cookie header automatically. It is attached even though the code does not add it anywhere. The server looks up abc123 and knows that the request is from member 7.
  4. This is the request for shop.example/shop/cart. This path falls under Path=/, so the cookie is attached.
  5. This is a request going to another site, other.example. The cookie that shop.example gave is not attached. A cookie is attached only to requests going to the host that sent it, shop.example (the Domain attribute can widen this).
  6. JavaScript on the shop.example/shop/cart page reads document.cookie. A cookie with HttpOnly is not visible to scripts. It is still attached to requests automatically.

Result of this run

Code

@PostMapping("/login")
ResponseEntity<Void> login(@RequestBody LoginRequest req) {
    Member m = memberService.check(req.id(), req.password());
    String sid = sessionStore.create(m.getId());        // "abc123" → member 7

    ResponseCookie cookie = ResponseCookie.from("sid", sid)
        .path("/")
        .httpOnly(true)
        .build();
    return ResponseEntity.ok()
        .header(HttpHeaders.SET_COOKIE, cookie.toString())
        .build();
}
// Response header: Set-Cookie: sid=abc123; Path=/; HttpOnly

Assumptions of this model

The paths that a cookie is attached to according to Path, the fact that an HttpOnly cookie is not visible in document.cookie, the disappearance of a cookie after its Max-Age has passed, and the fact that a cookie is not sent to an address on a different host are the same as the results checked with a real browser and a test server. That a session cookie is deleted when the browser is closed follows the standard behavior, and it was not checked by running it. A browser with the "restore previous tabs" feature turned on may bring session cookies back. The Secure, SameSite, and Domain attributes are not covered in this lab.

Previous lab: HTTP/1.1, 2, 3 · Next lab: HTTP caching and ETag

Concepts in this lab

What this lab shows

Settings

Code


      
    

Diagram

Run comparison

Try these