Authentication vs. Authorization: what is the difference?

Last updated: July 2026

Authentication is a check of who you are; authorization is the per-request decision of what you may do. Every secure system needs both. The hotel makes it concrete: your ID at the front desk is authentication; the keycard that opens room 412 — and only room 412 — is authorization. They are different questions, asked at different times, answered by different machinery, and they fail in different ways — which is why systems that blur them ship both kinds of breach.

Key takeaways

QuestionAnswer
Authentication (AuthN)Who are you? — credentials → identity, once per session
Authorization (AuthZ)What may you do? — policies → allow/deny, every request
The HTTP codes401 = unauthenticated (a misnomer) · 403 = known and refused
The protocol splitOIDC/SAML/passkeys = authn · OAuth scopes/RBAC/ACLs = authz
The failure splitAuthN fails as account takeover · AuthZ fails as privilege escalation

How Authentication and Authorization Run on One Request

1  POST /login  (credentials + MFA)          ── AUTHENTICATION, once
   ← session token / cookie: identity established

2  GET /documents/xKd91m                     ── every request thereafter:
   a · token validated        → identity re-established     (authn machinery)
   b · permission evaluated   → may ADA read THIS document? (authz decision)

   → 200  both passed
   → 401  no/invalid token — WWW-Authenticate challenge; logging in fixes it
   → 403  token fine, permission denied — logging in again fixes nothing
   → 404  some APIs hide forbidden objects entirely (RFC 9110 allows it)

The same split in application code — log in once, get judged per operation:

// JavaScript / Node.js — Back4app JS SDK
// Authentication: once — who are you?
const user = await Parse.User.logIn('ada', password); // session token issued

// Authorization: every request — may YOU do THIS?
const doc = await new Parse.Query('Document').get('xKd91m');
// found if an ACL entry grants ada read · "not found" if not

doc.set('title', 'Renamed');
await doc.save(); // succeeds only if an entry grants ada WRITE

Authentication vs. authorization, side by side

AuthenticationAuthorization
QuestionWho are you?What may you do?
InputsCredentials: passwords, MFA codes, passkeys, biometricsPolicies: roles, ACLs, attributes, scopes
FrequencyOnce per session (+ step-up for sensitive actions)Every request, every object
ProducesA session or tokenAn allow/deny decision
User sees itYes — the login screenRarely — it works invisibly
Where it runsThe edge: identity layer, login flowDeep: business and data layer, beside the data
ProtocolsOpenID Connect, SAML, WebAuthnOAuth 2.0 scopes, RBAC/ABAC/ReBAC engines
Standard bearerID token — who authenticatedAccess token — what the bearer may do
Fails asAccount takeoverPrivilege escalation, data exposure

Two rows deserve their footnotes. Where it runs: authentication naturally concentrates at the edge — one login flow, one identity provider — while authorization belongs next to the data it protects, because “may this user touch this object” needs the object. Fails as: the threat models are disjoint — credential stuffing and phishing attack authentication (which is why MFA is the highest-leverage authn defense), while broken object-level authorization tops API security lists as the signature authz failure: logged-in user, wrong object, nobody checked.

Authentication once, authorization on every requestA user authenticates once with credentials and receives a session token. Every subsequent request passes token validation, which re-establishes identity, and then a per-request authorization check against roles, ACLs, and policies before the resource is served; failures return 401 for missing authentication and 403 for denied permission.

credentials, once

session / token

no → 401

yes

no → 403

yes

User

Authentication
login + MFA

Each request

Token valid?

401 + WWW-Authenticate

Authorized for THIS
resource + action?

403 (or 404 to hide)

Resource

A user authenticates once with credentials and receives a session token. Every subsequent request passes token validation, which re-establishes identity, and then a per-request authorization check against roles, ACLs, and policies before the resource is served; failures return 401 for missing authentication and 403 for denied permission.

401 and 403, precisely

The status codes are the distinction wearing numbers, and RFC 9110 is exact about it. 401 Unauthorized is history’s most durable misnomer: it means unauthenticated — the request “lacks valid authentication credentials,” the response must carry a WWW-Authenticate challenge, and presenting credentials can fix it. 403 Forbidden means the server understood exactly who was asking and refuses anyway — re-authenticating is pointless by definition. And the spec blesses a third move security teams love: answering 404 instead of 403, so a forbidden resource doesn’t confirm its own existence. Getting the codes right isn’t pedantry; clients build retry and re-login logic on them, and a 403 that should be a 401 sends users into a wall instead of a login form.

OAuth, OIDC, and the eternal confusion

The confusion has a spec-shaped answer. OAuth 2.0’s title is “The OAuth 2.0 Authorization Framework” — it moves scoped permissions, and the OpenID Connect spec exists precisely because OAuth alone “is incapable of providing information about the authentication of an end-user.” OIDC adds the identity layer: an ID token asserting who authenticated, distinct from the access token asserting what the bearer may do. Every “Sign in with…” button is OIDC doing authentication over OAuth’s authorization plumbing — one flow, both concepts, cleanly layered rather than confused.

The three mistakes that ship

Client-side authorization. Hiding the delete button is interface design; the server deciding whether delete executes is security. Per OWASP: deny by default, enforce server-side, and treat client checks as UX hints. Logged-in ≠ allowed. Checking authentication but not object ownership — /documents/42 served to any valid session — is broken object-level authorization, the most common API vulnerability class. The check is per-object, per-request, no exceptions. Middleware order. Authenticate first, authorize second, in code as in concept: the identity middleware establishes who, then handlers ask whether — and an authorization check that runs before identity is established silently authorizes the anonymous.

Common use cases

  • App login + data permissions — the everyday pairing: one auth flow, per-object rules on everything after.
  • API design — 401/403 semantics, scoped tokens, and object-level checks as the contract’s error language.
  • Multi-tenant SaaS — authentication shared across tenants; authorization scoped hard inside each one.
  • Admin and support tooling — step-up authentication and elevated authorization, deliberately separate events.
  • Public + private content — anonymous read as an authorization rule, proving the two concepts run independently.

Which check are you missing? A decision matrix

SymptomMissing piece
Anyone with a link reads private dataAuthorization — per-object checks
Stolen passwords keep workingAuthentication — add MFA
Users see 403 walls after login errorsWrong code — that’s a 401 flow
Any logged-in user can hit admin APIsAuthorization — roles, deny by default
”Log in with…” treated as authorizationConcept mix — OIDC authenticates; scopes authorize
Buttons hidden but endpoints openAuthorization enforced only client-side

Limitations and trade-offs

  • The split is conceptual, not always architectural. Small apps reasonably run both in one middleware stack; the discipline is keeping the checks distinct, not the servers.
  • Strong authn can’t rescue weak authz. Passkeys and MFA verify identity flawlessly for a system that then lets anyone read anything — the failures are independent.
  • Per-request authorization has a cost. Caching decisions, pushing rules into the data layer, and indexing permissions are how “check everything” stays fast.
  • Step-up blurs the timeline. Sensitive actions re-authenticate mid-session — authentication isn’t strictly “once,” it’s “once per assurance level.”
  • Vocabulary drift causes real bugs. Teams saying “auth” for both halves write tickets, tests, and error codes that conflate them; the words are the cheapest defense.

Authentication and authorization on Back4app

Back4app is an open-source Backend-as-a-Service (BaaS) platform that combines a managed database, auto-generated REST and GraphQL APIs, authentication, file storage, and Cloud Code serverless functions. The platform’s architecture is the split: the User class, sessions, social login, and the MFA adapter answer who you are, producing a revocable session token — and then ACLs, class-level permissions, and roles answer what you may do, evaluated server-side on every REST, GraphQL, and Live Query request, exactly as the code tabs show: log in once, get judged per operation. The mistakes section becomes structural: authorization can’t be client-side because Back4app enforces it behind the API, unauthorized objects come back as not-found rather than confirming their existence, and deny-by-default is one checkbox on a class. The two questions stay separate because the platform never lets them merge.

Frequently asked questions

What is the difference between authentication and authorization in simple terms?

Authentication verifies who you are — credentials, codes, biometrics. Authorization decides what you may do — roles, permissions, policies. Hotel version: showing ID at the front desk is authentication; the keycard that opens your room but not the penthouse is authorization.

Which comes first, authentication or authorization?

Authentication, almost always — a system cannot grant permissions to an unknown party. The instructive exception: public resources are authorization decisions made without authentication; "anyone may read this" is still a permission rule, applied to the anonymous.

What are examples of each?

Authentication: password plus a TOTP code, a passkey ceremony, signing in with an identity provider. Authorization: an admin can delete users while a viewer cannot; a document readable by its owner and one shared reviewer; an API token scoped to read-only.

What is the difference between a 401 and a 403 error?

401 means the request lacks valid authentication credentials — despite its official name "Unauthorized," it really means unauthenticated, and logging in can fix it. 403 means the server knows who you are and refuses anyway — permission denied, and logging in again changes nothing.

Can you have authorization without authentication?

Yes — every public endpoint is proof: anonymous access is an authorization rule evaluated without an identity. The reverse also exists: authenticated but authorized for nothing, which is exactly what a fresh account with no roles should be.

Which protocols handle authentication and which authorization?

Authentication: passwords, MFA, passkeys and WebAuthn, sessions, OpenID Connect, SAML. Authorization: roles (RBAC), attribute rules (ABAC), ACLs, OAuth 2.0 scopes, policy engines. OAuth famously sits on the authorization side — its login reputation comes from OpenID Connect riding on top of it.

Is OAuth authentication or authorization?

Authorization — the spec's own title is "The OAuth 2.0 Authorization Framework," and the OpenID Connect spec exists precisely because OAuth alone cannot attest who authenticated. Every real "Sign in with…" button is OIDC adding an identity layer over OAuth's plumbing.

How do authentication and authorization work together in a request?

Authenticate once at login, producing a session or token. Then, on every request, the server re-establishes identity from that token and evaluates authorization for the specific resource and action. Once per session versus every single request — that asymmetry is the whole architecture.

What are the most common mistakes?

Confusing the two in error handling (403 where 401 belongs), enforcing authorization in the client (hiding buttons is UX, not security), and checking that a user is logged in but not that they own the specific object — the broken-object-level-authorization hole that tops API security lists.

Related terms

Compare with

Further reading

Ready to build your backend?

Start your project on Back4app in minutes — database, auth, APIs, and Cloud Code included. No credit card required.

Written and reviewed by Back4app Engineering, Back4app Engineering · Published 2026-07-30