Authentication vs Authorization
“Auth” is often used loosely to mean both authentication and authorization. Understanding the difference between them is essential for building a secure API.
Authentication: who are you?
Section titled “Authentication: who are you?”Authentication verifies identity. When a user logs in with a username and password, the server checks the credentials and confirms: “Yes, this is Alice.”
Authentication answers: Who is making this request?
Authorization: what can you do?
Section titled “Authorization: what can you do?”Authorization controls access. Once the server knows who you are, it decides what you’re allowed to do: “Alice can edit her own posts but not Bob’s.”
Authorization answers: Is this person allowed to do this specific thing?
Why both matter
Section titled “Why both matter”In Bulletin:
- Authentication: verify username + password, issue a token
- Authorization: only the post’s author can delete it, only authenticated users can post
A request without a token is unauthenticated — we don’t know who it is (401 Unauthorized). A request with a valid token from a user who doesn’t own the post is authenticated but unauthorized (403 Forbidden).
Session-based auth
Section titled “Session-based auth”The traditional approach:
- User logs in — server creates a session record in a database
- Server sends the session ID in a cookie
- Browser sends the cookie with every subsequent request
- Server looks up the session ID in the database on each request
Pros: Easy to invalidate sessions (delete the record), works well for same-domain web apps.
Cons: Requires server-side session storage, harder to scale across multiple servers, cookie-based which adds CSRF complexity.
Token-based auth (JWT)
Section titled “Token-based auth (JWT)”The stateless approach used by the Bulletin API:
- User logs in — server creates a signed token (JWT) containing the user’s ID
- Server sends the token to the client
- Client stores the token (localStorage or memory)
- Client sends the token in the
Authorization: Bearer <token>header - Server verifies the token’s signature — no database lookup needed
Pros: Stateless (no session storage), works across multiple servers and domains, natural for API + SPA architecture.
Cons: Tokens can’t be invalidated until they expire (without additional infrastructure), tokens live in JavaScript memory/storage (XSS risk).
Which to use?
Section titled “Which to use?”For an API serving a React SPA (like Bulletin), JWT tokens are the standard choice:
- The API and frontend can be on different domains
- No shared session storage needed between API servers
- React handles the token in state/localStorage
For traditional server-rendered web apps where the server and frontend are on the same domain, sessions are often simpler and safer.
The Bulletin auth flow
Section titled “The Bulletin auth flow”POST /auth/register Body: { username, password } → Hash password with bcrypt → Insert user into database → Sign and return JWT
POST /auth/login Body: { username, password } → Find user by username → Compare password with bcrypt → Sign and return JWT
GET /posts (protected) Header: Authorization: Bearer <token> → Verify JWT signature → Extract user ID from payload → User is authenticated — proceedExercise
Section titled “Exercise”No code yet. Think through the Bulletin auth flow:
- What data should the JWT payload contain? (What does the API need to know about the current user?)
- What HTTP status code should a request with no token get? What about a request with a valid token but trying to delete someone else’s post?
- What happens if a token is stolen? How long should tokens be valid?
- Authentication verifies identity (who are you?); authorization controls access (what can you do?).
- 401 Unauthorized = not authenticated; 403 Forbidden = authenticated but not allowed.
- Session-based auth stores state on the server; token-based auth (JWT) is stateless.
- JWTs are ideal for APIs + SPAs: different domains, no shared session storage needed.