// Security · 02
OAuth 2.0 & OpenID Connect
Delegated sign-in: the app gets a token for an API, not the password.
How it fits together
- Browser uses / calls Identity provider (1 authorize+PKCE)
- Identity provider publishes / notifies Browser (2 redirect+code)
- Browser uses / calls Client app (3 code to app)
- Client app uses / calls Identity provider (4 code+verifier)
- Identity provider creates Client app (5 ID + access)
- Client app uses / calls Orders API (6 Bearer token)
Spot it
- Users type passwords into our own login form
- Tokens leak in URLs or browser storage
- Single sign-on needed across several apps
It costs
More redirects, and sign-in depends on an identity provider being available.
Go deeperThe full explanation and what to ask for · 1 min readExpandCollapse
OAuth 2.0 is delegated authorisation: a user lets an app obtain a token that works on an API, without giving the app their password. OpenID Connect adds a standard sign-in layer on top. The ID token tells the app who the user is and is meant for the client; the access token is meant for the API, and the client should treat it as opaque.
Use the authorization code flow with PKCE, for browser and mobile apps alike. The app creates a random code_verifier and sends its SHA-256 hash as the code_challenge when it redirects. It then proves possession by sending the verifier with the code, so an intercepted code is useless on its own. The implicit flow is deprecated for exactly this reason.
Scopes say what the token may do (orders.read), and the audience says which API may accept it; check both on every request. A refresh token, requested with offline_access, lets the app renew access quietly; keep it server-side or in a secure store, and rotate it. When NOT to: do not build your own identity provider or login screens, since password storage, MFA and account recovery are easy to get wrong.
Ask for it
- authorization code + PKCE
- ID token vs access token
- scope
- audience (aud)
- identity provider (IdP)
- refresh token
Add sign-in with authorization code + PKCE (S256): redirect to the identity provider with a code_challenge, exchange the code and code_verifier at its token endpoint, call the API with the access token (aud orders-api, scope orders.read), never send the ID token to the API.