What You'll Learn
- The precise difference between authentication and authorization
- Why this difference matters in API design
- Real examples of each
- Common mistakes that cause security bugs
Why This Matters
These two words get conflated constantly — in casual conversation, in documentation, even in tool names. But they describe two completely different checks, and confusing them leads to broken access control, leaked data, and security vulnerabilities. Get them straight and you'll think about API security more clearly than most developers.
Simple Definitions
Authentication (authn) answers: Who are you?
Authorization (authz) answers: Are you allowed to do this?
Authentication proves identity. Authorization grants permission. The two are sequential: you must authenticate before the server can decide what you're authorized to do.
Real-World Analogy — Airport Security
At an airport:
- Check-in desk: You show your passport. The agent verifies your identity. This is authentication.
- Boarding gate: The agent scans your boarding pass. They check whether this passenger is allowed on this flight. This is authorization.
You can be authenticated (passport is real) but not authorized (you don't have a ticket for this flight). You can be authorized (you have a ticket) but if your passport is fake, you fail authentication. Both checks must pass.
How They Show Up in APIs
Authentication
You send a credential — an API key, a username/password, a token — and the server verifies it. If valid, the server knows who you are. If not, you get 401 Unauthorized.
GET /users/me HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
The server decodes the token, looks up the user, and now knows "this is Anita".
Authorization
Once authenticated, the server checks whether Anita is allowed to do what she's trying to do. Can she delete this post? Is she an admin? Does she own this resource? If not, you get 403 Forbidden.
DELETE /posts/456 HTTP/1.1
Authorization: Bearer <Anita's token>
The server checks: is Anita the owner of post 456? If post 456 belongs to Ravi, the server returns 403, not 401. The server knows who Anita is (authentication passed) but she cannot delete someone else's post (authorization failed).
The Status Code Distinction
| Code | Meaning | Failed check |
|---|---|---|
| 401 Unauthorized | "I don't know who you are" | Authentication |
| 403 Forbidden | "I know who you are, but you can't do this" | Authorization |
Real Examples
Example 1 — Reading your own profile
GET /users/123
Authorization: Bearer <Anita's token, user ID 123>
Authentication: token is valid, identifies Anita. Authorization: Anita is allowed to read her own profile. Result: 200 OK.
Example 2 — Reading someone else's profile
GET /users/456
Authorization: Bearer <Anita's token, user ID 123>
Authentication: passes. Authorization: depends on the API. Public APIs may allow it (200 OK). Private APIs may return 403.
Example 3 — Deleting someone else's post
DELETE /posts/456
Authorization: Bearer <Anita's token>
Post 456 belongs to Ravi. Authentication: passes. Authorization: fails — Anita is not the owner and is not an admin. Result: 403 Forbidden.
Example 4 — Sending an expired token
GET /users/me
Authorization: Bearer <expired token>
Authentication: fails — token is expired, server cannot identify you. Authorization: cannot be checked because authentication failed. Result: 401 Unauthorized.
Where Each Happens in the Request Lifecycle
- Request arrives at server.
- Authentication check: Server reads the
Authorizationheader (or cookie, or API key) and verifies it. If invalid → 401. - Routing: Server figures out which endpoint handles this URL.
- Authorization check: Server checks if the authenticated user can perform this action on this resource. If not → 403.
- Business logic: Server does the actual work.
- Response.
Common Mistakes
- Using 401 for permission errors. If the user is authenticated but lacks permission, return 403, not 401.
- Skipping authorization because "they're logged in". Authentication is not authorization. A logged-in user can still try to access other users' data.
- Trust-the-client authorization. Never let the frontend decide what the user can do. The server must enforce authorization on every request.
- Confusing "admin" with "owner". An admin can do many things, but ownership is a separate check. A user can be an admin without owning a specific resource.
- Forgetting to authorize sub-resources. "Anita can read post 456" does not mean "Anita can read post 456's comments by another user". Check each level.
Practical Exercise (5 minutes)
For each scenario, decide: is this an authentication failure, an authorization failure, or both?
- User sends no
Authorizationheader. - User sends an expired token.
- User sends a valid token but tries to delete another user's post.
- User sends a valid token but tries to access a premium feature on a free plan.
- User sends a malformed token.
- Admin user tries to access another admin's private settings.
Answers: 1. Authentication (401). 2. Authentication (401). 3. Authorization (403). 4. Authorization (403). 5. Authentication (401). 6. Authorization (403).
Mini Challenge
Audit any API you have built or worked with. For each endpoint, ask: (1) Does it check authentication? (2) Does it check authorization? (3) Are the checks done on the server, not the client? You will likely find at least one endpoint that skips authorization "because the user is logged in". That is a security bug.
Key Takeaways
- Authentication = who are you? Authorization = are you allowed?
- 401 = authentication failed. 403 = authorization failed.
- Authentication happens first; authorization happens after.
- A logged-in user is not automatically authorized for every action.
- Always enforce authorization on the server, never trust the client.
Previously: Module 4 (lessons 22–25) covered calling APIs.
Today: You learned the foundation of API security — the difference between auth and authz.
Next: Lesson 27 covers the simplest form of authentication: API keys.
FAQ
Why is 401 called "Unauthorized" if it means unauthenticated?
Historical accident. The HTTP/1.0 spec (RFC 1945, 1996) named it "Unauthorized" and the name stuck. RFC 9110 keeps the name for compatibility. Most developers mentally translate "401 Unauthorized" to "401 Unauthenticated".
Can authorization happen without authentication?
Technically yes — public endpoints might allow anyone but with different limits (anonymous: 10 requests/hour, authenticated: 100). But for any operation that affects data, you need authentication first to know whose authorization to check.
Comments
Comments
Post a Comment