Skip to content
API Design Learn/Auth & Versioning
Browsing as a guest. Sign in to save your progress and earn XP as you complete chapters.

Authentication & Authorization Basics

7 min read

You'll learn to

  • -Distinguish authentication (who are you) from authorization (what can you do), and know which status code fits which failure
  • -Implement bearer token authentication and understand what a refresh token flow buys you

Authentication and authorization are two different questions that get conflated constantly, including in status codes - and the distinction is exactly what a strong API design answer names explicitly instead of treating "auth" as one undifferentiated concept.

Authentication vs. Authorization

  • -Authentication ("who are you?"): verifying the caller's identity - a valid, unexpired credential. Failure here is 401 Unauthorized.
  • -Authorization ("what can you do?"): given a known identity, deciding whether this specific action on this specific resource is allowed. Failure here is 403 Forbidden.
401 vs. 403 - a genuinely different failure each time
# No credential at all, or an expired/invalid one - identity unknown
GET /admin/reports
Authorization: Bearer expired-token-xyz
HTTP/1.1 401 Unauthorized

# Identity IS known (valid token), but this user isn't allowed to do this
GET /admin/reports
Authorization: Bearer valid-token-for-regular-user
HTTP/1.1 403 Forbidden

Getting this backwards (401 for a permissions failure, or 403 for a missing credential) genuinely confuses clients: a well-behaved client that sees 401 knows to try re-authenticating (refresh the token, prompt for login again); a client that sees 403 knows re-authenticating won't help, since the identity was fine and the problem is permissions. Swap the two and clients end up in unproductive retry loops.

Bearer Tokens and the Refresh Flow

The standard bearer-token authentication header
POST /auth/login
{"email": "ada@example.com", "password": "..."}

HTTP/1.1 200 OK
{"access_token": "eyJhbGc...", "refresh_token": "8f3a...", "expires_in": 900}

# every subsequent authenticated request carries the access token:
GET /orders
Authorization: Bearer eyJhbGc...

Access tokens are typically short-lived (minutes), which limits the damage window if one leaks - but re-logging in every 15 minutes would be unacceptable for users. A refresh token (longer-lived, used only against `/auth/refresh` to mint a new access token) solves this: the short-lived token limits exposure, and the longer-lived refresh token lets that exposure-limiting happen transparently to the user, without repeated logins.

A refresh token should be usable only to mint new access tokens - never accepted directly as a substitute for one on ordinary API calls. Keeping that boundary strict limits what a leaked refresh token alone can actually do.

Interview Signal is part of Pro

See a real weak answer next to a real strong one for this exact topic.

Quiz is part of Pro

Test what you just read with a short quiz, and bank the XP.

Ready to Build This?

Design The Gatekeeper in the API Design Lab's REST Foundations act.

ScaleDojo Logo
Initializing ScaleDojo