A browser or curl asks a server for a protected page, one HTTP message at a time — see every header of the challenge and the credentials, set the users and passwords on both sides, change them mid-way, and turn on a session cookie to see what the server starts keeping.
HTTP keeps nothing between requests, so a server that wants to know who is asking must be told on every
request.
- Basic authentication, defined in
RFC 7617, does it the
simplest way: every request carries the username and password in a header.
- The tool shows each message whole, so the password can be read crossing the wire.
- Each side's settings can be changed, to see what the other side does with it.
Reading the drawing
- The client is a browser window or a curl command line. Both keep what a real one keeps: the
credentials it remembers, and the cookies it was given.
- On a 401, the browser's sign-in dialog blocks the tab until we sign in or cancel.
- The server holds the realm, the users and their passwords, and lists the checks it ran on the last
request, one line per check.
- The wire shows the current step's message, every line of it. A click on a line says what it does;
the line the step is about opens by itself.
- Step plays the story, one message at a time, in five scenes: the challenge, wrong passwords, a
password change, curl, and a session cookie. The server answers by its settings, so its response is
always the step after a request.
- Messages so far, on the right, is the scene as a sequence diagram. A dot on a line is a change of
settings, and a click on a row goes back to it.
- The buttons and fields on either side take the story our own way: the rest of the story gives way
to what we do. The scene picker or Restart brings it back.
The challenge and the credentials
A browser sends credentials only once a server asks for them, so the first request for a protected page
costs a round trip.
- The first request carries nothing. The server answers
401 Unauthorized with
WWW-Authenticate: Basic realm="course". - That header is the challenge. It names the scheme and the realm, the name of the protected area.
- A browser files the password it remembers under the site and the realm.
- It leaves the realm out of its sign-in dialog, because a site could write anything there.
- The header alone asks for the login. The browser shows the 401's body only if we cancel the dialog.
A site that logs in with a form works the other way:
- its body carries the HTML form;
- it sends no
WWW-Authenticate header.
- The second request carries
Authorization: Basic, followed by the username and password joined
with a colon and base64-encoded. - The server decodes the header, splits it at the first colon (a username may not contain one), and
compares the password with the one it holds.
- curl with
-u skips the challenge: it builds the header before the first request.
base64: an encoding anyone can reverse
YWxpY2U6c2VjcmV0MTIz is alice:secret123 written in a 64-character alphabet, so that any byte
survives inside a header.
- Reversing it takes no key, which is why the tool can show the decoded value under every
Authorization line. - Over plain
http://, every machine on the path can do the same. - So Basic authentication is acceptable only inside TLS.
What each side keeps between requests
- The server keeps nothing. It checks the password on every request, from the start, and keeps no
count of failures.
- The browser keeps the password. After a successful sign-in it adds the same header to every later
request to the site (
RFC 7617, section 2.2).
- The password crosses the wire again and again.
- Forget drops it. Closing the browser does the same, and it is the only way to log out.
- A password changed on the server reaches a client only as a 401: the browser keeps sending the old
one, gets a 401, and shows its dialog again.
A session cookie: the server starts keeping state
Set a session cookie after a correct password makes the server remember, which Basic authentication
does not include.
- After a correct password, the server creates a random session id, records which user it belongs
to, and sends it in
Set-Cookie. - The browser returns the id in a
Cookie header on every request, and the server accepts it in place
of the password. With the password forgotten in the browser, the requests still succeed. - Revoking the session on the server makes the cookie worthless at once: a logout, which Basic
authentication alone cannot do.
- The price is state on the server: a session table it must keep, share between its instances and
expire.
The course
Authentication and Secrets builds the same exchange
with nginx and curl in its chapter HTTP is stateless.