Q1When the server stores a user's password, what is placed in the database?
How Login Works — Authentication, Sessions, and Cookies
This article is part of the IT Foundations course, which builds up from scratch the practical IT knowledge you need at a minimum for programming and vibe coding.
A login feature is made of authentication, which confirms that a user really is who they claim to be, and a session, which lets the server keep recognizing that same user afterward. The diagrams show what the hash and the Cookie each do.
This article covers how a login feature works.
A login feature is made of two mechanisms: one that confirms a user is who they claim to be, and one that keeps recognizing that same user afterward.
"Hashing," "session-based authentication," and "JWT" are different names for parts of one login feature.
The upper branch is the check done only once; the lower branch is the check done on every request after that.
Authentication confirms who you are; authorization decides what you may do
Authentication — confirming that a user really is who they claim to be — is the decision made at login.
Authorization — deciding what that confirmed user is allowed to do — is a separate decision made afterward.
- What it uses — ID and password; after login, the session ID in the Cookie
- If it fails — send the user back to the login screen
- The password is checked once; after that, the session ID
- What it uses — who owns the booking, and whether the user is an admin
- If it fails — return "you do not have permission"
- Checked every time an action is taken
Even for actions by the same tanaka, the two are decided separately.
Some rows stop at authentication, and some pass authentication and then stop at authorization.
Settings like "admins only" and "you can see only your own data" are authorization.
Authentication confirms who you are; authorization decides what you may do
Being able to log in and being allowed to perform an action are decided separately.
Authentication confirms whether a user is who they claim to be, authorization decides whether that user may perform that action, and authorization is checked on the server every time an action is taken.
Passwords are stored as hashes, and hashes are compared with hashes
The first thing to understand about authentication is that the server does not store the password itself.
What is stored is a hash — a string produced from the original string by a fixed procedure, which cannot be turned back into the original.
| What you type | Hashed on the spot | Compared with the stored hash | Result |
|---|---|---|---|
| hanabi2026 (correct) | a3f9...c1 | Same as a3f9...c1 | Login succeeds |
| hanabi2025 (one character different) | 7b20...e4 | Different from a3f9...c1 | Login fails |
| Hanabi2026 (different capitalization) | d15c...8a | Different from a3f9...c1 | Login fails |
A single different character produces a completely different hash.
The check still works even though the hash cannot be reversed, because what it is compared against is also a hash.
All the server holds is a string that cannot be reversed.
- email — tanaka@example.com
- password_hash — a3f9...c1
- created_at — the date and time the account was created
- The typed characters hanabi2026
- Any data that can be turned back into the typed characters
- Whether the user is currently logged in
Passwords are stored as hashes in case the contents of the database leak.
Commonly used strings can be guessed, so a different string for each user (a salt) is added before hashing.
HTTPS protects the data from being read while it travels, which is separate from the form it is stored in.
What is stored is a hash, and what it is compared against is a hash too
The server does not hold the password the user typed.
All it holds is a string that cannot be reversed, and at every login it runs the typed characters through the same procedure and checks whether the resulting string is the same as the stored one.
After login, the session ID in the Cookie is how the server knows it is the same person
Even after a successful login, the request that opens the next page is a separate request.
HTTP is stateless — one exchange does not remember the previous one — so the server does not keep track of who logged in a moment ago.
The fact that the login passed is recorded on the server, and the browser is handed a string that points to that record.
The record kept on the server is the session, the string that points to it is the session ID, and the mechanism that hands that string to the browser and has it sent every time is the Cookie.
- Cookie: session_id=3f9a1c...e81b
- Attached automatically to every request to the same site
- Nothing besides this string is held
- Session record 3f9a1c...e81b is tanaka
- This record has an expiry
- Logging out deletes this record
All that is on the browser side is the string 3f9a1c...e81b, which holds no name and no permissions.
Whose login it is becomes clear only when that string is matched with the record on the server.
Only the upper row is matched with a record, so the booking list comes back without asking for the password again.
This hand-off takes the form of the following two lines.
# The line the server returns when login succeeds
Set-Cookie: session_id=3f9a1c...e81b; HttpOnly; Secure
# From then on, the line attached to every request the browser sends to the same site
Cookie: session_id=3f9a1c...e81b
The two items after Set-Cookie are instructions to the browser.
HttpOnly keeps the JavaScript on the page from reading this Cookie, and Secure makes it sent only over HTTPS.
The contents of a Cookie can be rewritten by the user, so the result changes depending on whether they are trusted as they arrive.
A Cookie is stored in the browser, so the user can rewrite its contents and send it.
Put only the session ID in the Cookie, and make the decision from the record on the server.
The box on the left holds just one string with no meaning of its own.
Everything that decides who a user is and what they may do sits inside the box on the right.
The browser is handed just one string that points to the record
At the moment a request arrives, the server does not know who it is from.
It finds out because the record created at login and the string the browser sends every time are matched, and if the record is deleted or expires, sending the same string takes you back to the login screen.
Session-based authentication vs JWT — does the server hold the record, or does the string?
"Session-based or JWT" is a choice about which side holds the proof of being logged in.
The other approach leaves no record on the server and gives the proof itself to the browser.
The string of proof attached and sent every time is a token, and JWT (JSON Web Token), a string that bundles a user ID, an expiry, and a signature, is the best-known format.
- tanaka's user ID
- Expiry (usable until this time)
- A string computed from the contents
- Rewriting the contents makes the computation stop matching
Because of the signature, the server can tell that the string that arrived is one it issued, without checking it against a record.
| Aspect | Session-based authentication | JWT |
|---|---|---|
| What is handed over on a successful login | session_id=3f9a1c...e81b | eyJhbGci... ID, expiry, and signature |
| Where the basis for the decision sits | A record inside the server | The contents inside the string |
| How it is checked each time | Match it against the record | Verify the signature |
A JWT carries its contents, so it can be accepted without a record on the server.
With session-based authentication, deleting the record stops the next request from passing.
A JWT passes until its expiry, so when you want to stop it immediately, you keep a separate list of the ones you have revoked.
This article drew session-based authentication as a Cookie and JWT as a string, but in practice there are setups that put a JWT in a Cookie.
Even when where it is kept changes, the difference — matching against a record or verifying a signature — stays the same.
Does the server hold the record, or does the string hold the contents itself?
In both approaches, the browser attaches and sends one string every time.
What differs is what the server does when it receives it: session-based authentication looks up its own record, while JWT verifies the signature attached to the string.
Knowledge Check
Answer each question one by one.
Q2When you open another page after logging in, why does the server know it is the same user?
Q3A logged-in user tried to delete someone else's booking and was refused by the server. Which decision is this?