Walk me through the OAuth 2.0 authorization code flow.
Short answer
The app redirects the user to the authorization server to log in and consent. The server redirects back with a short-lived authorization code. The app's backend then exchanges that code (plus its client secret) at the token endpoint for an access token, over a server-to-server back channel. This keeps tokens out of the browser/URL. Public clients add PKCE to bind the code to the original requester.
OAuth 2.0 confuses a lot of candidates because they conflate it with login. OAuth is about delegated authorization — letting an app act on a resource on the user's behalf — not about identifying the user (that's OIDC, layered on top). The authorization code flow is the secure default.
The flow, step by step
- Redirect to authorize. The app sends the user's browser to the authorization server with its client ID, the requested scopes, a redirect URI, and a
statevalue (CSRF protection). - User authenticates and consents. The user logs in at the authorization server — the app never sees the password — and approves the requested scopes.
- Code returned. The authorization server redirects back to the app's registered URI with a short-lived, single-use authorization code in the query string.
- Back-channel exchange. The app's backend posts that code, plus its client secret, to the token endpoint and receives an access token (and often a refresh token). This step happens server-to-server, not in the browser.
- Call the API. The app uses the access token as a bearer credential to call the resource server.
Why this design
The key insight is that the powerful access token never travels through the browser or a URL, where it could be logged, cached, or leaked via referrer headers. Only the low-value, short-lived code does, and the code is useless without the client secret. This is why the code flow is preferred over the now-deprecated implicit flow, which exposed tokens directly in the redirect.
PKCE for public clients
Mobile apps and SPAs can't keep a client secret. PKCE (Proof Key for Code Exchange) fixes this: the client sends a hashed random code_challenge up front and the matching code_verifier at token exchange, proving the same client that started the flow is finishing it — so a stolen code can't be redeemed by an attacker.
What interviewers look for
The redirect/consent/code/back-channel-exchange sequence, the reason tokens stay off the browser, code-flow over implicit, and PKCE for clients that can't hold a secret. Bonus for noting OAuth is authorization, OIDC is authentication.
Likely follow-ups
- What problem does PKCE solve, and why do mobile/SPA clients need it?
- Why is the authorization code flow preferred over the implicit flow?
- What's the difference between OAuth 2.0 authorization and OpenID Connect authentication?