Skip to main content
Authentication7 min readPublished September 19, 2026Updated September 22, 2026

Authentication vs authorization

Authentication establishes identity — you are the holder of this account. Authorization establishes permission — this account may do this thing. Authentication happens once per session; authorization happens on every action, and it is the one people forget.

What does authentication actually produce?

A session: a signed token your app receives after a successful login. The token names the user and has an expiry. Every later request carries it, and the server verifies the signature rather than looking the password up again.

  1. 1User proves identity: password, magic link, or a provider like Google.
  2. 2The auth service issues a token with an expiry.
  3. 3The browser stores it and sends it with each request.
  4. 4The server verifies the signature and reads the user id from it.
  5. 5The token expires and is silently refreshed, or the user is signed out.

Where does authorization happen?

Everywhere the answer depends on who is asking: which rows a query returns, whether a delete is allowed, whether an admin page renders. It must be enforced on the server or in the database. Front-end checks are a convenience for the user, not a security control — hiding a button does not protect the action behind it.

CheckWhere it belongsWhy
Hide the admin linkFront endCosmetic only
Refuse the admin actionServer or databaseAnyone can call the endpoint directly
Return only your rowsDatabase access rulesCannot be bypassed by editing code

Where should roles be stored?

In their own table, keyed by user, checked server-side. Never in a field the user can edit, and never in browser storage. A role kept on a profile row that the user is allowed to update is a privilege-escalation bug waiting to be found.

The test: could a determined user change this value themselves? If yes, it is not a permission system.

How do the two fail differently?

FailureTypeSignal
No token sentAuthentication401, and the same result signed out
Expired tokenAuthentication401 after a period of inactivity
Valid user, wrong recordAuthorization403, or an empty result from access rules
Role missingAuthorizationWorks for you, fails for a new account

What do AI-built apps get wrong here?

  • Checking permission in the component and nowhere else.
  • Storing an `is_admin` flag on an editable profile row.
  • Fetching data with admin credentials to make a query work, quietly removing every access rule.
  • Leaving a callback URL pointing at localhost, so login works in development and dead-ends in production.

Frequently asked questions

Is OAuth authentication or authorization?
Both, historically. OAuth was designed to delegate permission, and sign-in-with-Google layers identity on top of it.
Why am I logged out after a redirect?
The session usually has not hydrated yet, or the redirect landed on a different origin than the one holding the session.
Do I need roles for a small app?
Not always. Owner-based rules — you may touch your own rows — cover most small apps without any role system at all.

Practice this in MessyDev

Reading it once helps. Doing it once sticks. These are the hands-on parts of MessyDev that cover the same ground.

Keep going