- OAuth 2.0 — an authorization framework. It lets an app get a token to act on your behalf (e.g. "read my calendar"), without ever seeing your password. It says nothing about who you are.
- OpenID / OpenID 2.0 — an older, separate authentication protocol (login only, no API access). Mostly dead now, replaced by OIDC.
- OpenID Connect (OIDC) — an identity layer built on top of OAuth 2.0. It adds an ID token (a signed JWT saying who the user is) alongside OAuth's access token (which grants API access). This is why almost every "Login with Google/Microsoft/etc." today is OIDC, not old OpenID.
OIDC = OAuth 2.0 + a standard way to authenticate.
| Role | Description |
|---|---|
| Browser (resource owner) | The user, acting through their browser |
| Client app | The web/mobile app requesting login and access |
| Authorization server (IdP) | Authenticates the user, issues tokens |
| Resource server | The protected API the client calls with the access token |
| Token | Who reads it | Purpose |
|---|---|---|
| ID token | Client app only | Proves who the user is (JWT with sub, email, etc.) |
| Access token | Resource server | Grants API access — doesn't carry identity by itself |
The ID token never leaves the client. Only the access token is forwarded to the resource server.
┌───────────┐
│ Browser │
│ (resource │
│ owner) │
└─────┬─────┘
│ login / redirect
┌─────▼─────┐
│Client app │
│(web/mobile│
│ app) │
└──┬─────┬──┘
id token + │ │ access token
access token │ │ only
┌────────▼┐ ┌▼────────────┐
│Authoriz-│ │ Resource │
│ation svr│ │ server │
│ (issues │ │ (protected │
│ tokens) │ │ API) │
└─────────┘ └─────────────┘
- Client ↔ Authorization server: gets ID token + access token
- Client → Resource server: sends access token only
- Authorization server and Resource server never talk directly (in the basic flow)
Solid arrows = front-channel (through the browser, via redirects). Dashed arrows = back-channel (direct server-to-server, browser never sees these).
Browser Client app Auth server Resource server
│ │ │ │
├──clicks login─►│ │ │
│ │ │ │
│◄─auth redirect─┤ │ │
│ │ │ │
├──────────────auth request─────────►│ │
│ │ │ │
│◄─────────────login + consent───────┤ │
│ │ │ │
│◄─────────────code returned─────────┤ │
│ │ │ │
├─callback(code)►│ │ │
│ │ │ │
│ ├╌╌tokens issued╌╌╌►│ │
│ │◄╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │
│ │ (id token + │ │
│ │ access token) │ │
│ │ │ │
│ ├╌╌╌╌╌╌╌╌╌╌╌╌access token╌╌╌╌╌╌╌╌╌╌╌╌╌╌►│
│ │◄╌╌╌╌╌╌╌╌╌╌╌╌╌protected data╌╌╌╌╌╌╌╌╌╌╌╌┤
- Clicks login — Browser opens the client app.
- Auth redirect — Client redirects browser to the auth server's
/authorizeendpoint (includesscope=openid,state, and a PKCEcode_challengefor public clients). - Auth request — Browser lands on the auth server with the authorization request.
- Login + consent — User authenticates and approves access.
- Code returned — Auth server redirects browser back to the client's
redirect_uriwith an authorization code. - Callback (code) — Browser delivers that code to the client app.
- Tokens issued (back-channel) — Client exchanges the code for tokens at the
/tokenendpoint (usingclient_secretor PKCEcode_verifier). Auth server returns both the ID token and access token. - Access token (back-channel) — Client calls the resource server's API with
Authorization: Bearer <access_token>— the ID token is not sent. - Protected data — Resource server validates the access token and returns the data.
stateparam — CSRF protection on the redirect.- PKCE (
code_challenge/code_verifier) — required for public clients (SPAs, mobile apps) that can't hold a secret. - Client must validate the ID token's signature,
iss,aud,exp, andnoncebefore trusting it. - Resource server should only ever need to validate the access token — it shouldn't need to parse it as identity info.