Authentication — Who Are You?
Anyone on the internet can send GET /orders/310 to the bookshop. Before answering, the server must know two things: who is asking, and whether that person is allowed to see order 310. Mixing these up is behind many real data leaks.
The rule
Authentication asks who you are; authorization asks what you may do.
- Authentication proves identity: a password, a login link, a key, a token.
- Authorization checks permission for that identity: "shoppers may read only their own orders", "only staff may change prices".
Each failure has its own status code:
| Situation | Status |
|---|---|
| No credentials, or invalid ones | 401 Unauthorized (despite the name, it means "not authenticated") |
| Known user, but not allowed | 403 Forbidden |
Some APIs return 404 instead of 403 when even admitting that a resource exists would leak information.
Passwords are never stored as typed. The server stores a hash made by a deliberately slow algorithm designed for passwords, such as Argon2 or bcrypt, with a random salt per user. At login it hashes the attempt the same way and compares. If the database leaks, attackers get hashes that are very expensive to reverse, not passwords. Fast general hashes such as MD5 or SHA-256 alone are the wrong tool, because attackers can try billions of guesses per second against them.
The simplest scheme is HTTP Basic authentication: the client sends the username and password with every request, only base64-encoded (not encrypted):
GET /orders/310 HTTP/1.1
Authorization: Basic YXNoYTpzZWNyZXQ=It works only over HTTPS and sends the real password constantly, so most apps instead log in once and then send a session cookie or a token, which the next lesson covers.
The shortcut
For every endpoint, ask the two questions in order: Who? If unknown → 401. Allowed? If not → 403. Only then do the work.
Who?
The request carries a valid session for user 12. Authenticated.
The trap is stopping after the first question: checking that someone is logged in, then returning whatever order id they ask for. Every lookup by id needs its own "is this yours?" check.
Drills
Answer fast — trust the rule.
A logged-in shopper tries PATCH /books/42 to change a price, which only staff may do. Which status fits?
A request arrives with no credentials at all for a protected endpoint. Which status fits?
How should the server store user passwords?
The API checks the user is logged in, then returns /orders/{id} for any id. What is missing?
Remember
- Authentication asks who you are; authorization asks what you may do.
- Who? No → 401. Allowed? No → 403. Then do the work.
- Store passwords only as salted hashes from Argon2 or bcrypt; never plain, never just base64.
