How it works
Start with four roles: the resource owner is the user, the client is the application requesting access, the authorization server issues tokens, and the resource server hosts the API. For example, a scheduling app can request permission to read a user’s calendar without learning their calendar account password.
For user-facing applications, use the authorization code flow with PKCE. The client creates a random verifier and derives an S256 challenge, then redirects the browser to the authorization endpoint with its client ID, requested scopes, registered redirect URI, challenge, and a state value bound to the browser session. The authorization server authenticates the user and obtains authorization, including consent when needed.
The authorization server redirects the browser back with a short-lived, single-use code and the state value. The client checks state and exchanges the code plus the PKCE verifier at the token endpoint over TLS. A confidential client also authenticates itself; a mobile app or browser application cannot safely keep a client secret.
The client receives an access token and may receive a refresh token. It sends the access token to the intended API, usually in the Authorization header. The API validates the token’s audience, expiration, scopes, and issuer as applicable, using signature verification for JWTs or an authorization-server lookup for opaque tokens. It must still enforce resource-level permissions, such as whether this user can read this particular calendar.
When the access token expires, the client can use a refresh token to request another one without another browser redirect. Protect refresh tokens as long-lived credentials; for public clients, use rotation with reuse detection or sender-constrained refresh tokens. In a backend-for-frontend design, keep tokens on the backend and give the browser a Secure, HttpOnly session cookie with appropriate CSRF defenses.
OAuth does not define a login identity assertion or require JWT access tokens. For federated login, add OpenID Connect and validate the ID token, including issuer, audience, expiration, and nonce when used. For a service acting as itself rather than for a user, consider the client credentials flow instead.
A worked example
Connecting a calendar to a scheduling app
A scheduling app needs read-only access to a user’s external calendar. Its backend starts authorization code with PKCE and requests calendar-read permission. After the user approves, the backend exchanges the returned code, stores the refresh token encrypted at rest, and gives the browser only a session cookie. Suppose access tokens last 10 minutes. Background workers use them to fetch events and coordinate refreshes per connection so two workers do not race a rotated refresh token. When the user disconnects, the app deletes its stored credentials, stops queued sync work, and requests provider revocation. An already-issued access token may remain usable until expiry unless the provider supports earlier invalidation.
Trade-offs to say out loud
- Short access-token lifetime versus refresh traffic
- Shorter lifetimes reduce the useful lifetime of a stolen token but increase dependence on the token endpoint.
- Local validation versus prompt revocation
- Locally validated JWTs avoid a lookup per request, but early revocation requires additional state or a bounded wait until expiration.
- Introspection versus authorization-server dependence
- Opaque-token introspection supports centralized validity checks, but adds latency and an availability dependency, while caching weakens revocation freshness.
- Browser simplicity versus token exposure
- A backend-for-frontend keeps OAuth tokens out of browser JavaScript but adds session infrastructure and still requires CSRF protection.
- Narrow scopes versus integration complexity
- Least-privilege scopes limit access, but require a clear permission model and sometimes additional authorization prompts.
- Refresh-token rotation versus concurrency
- Rotation helps detect replay, but concurrent refresh attempts and retries need coordination so legitimate clients do not accidentally invalidate their sessions.
When to reach for it
- A third-party application must access a user’s data without receiving that user’s password.
- The requirements include external identity-provider login, where OAuth handles authorization and OpenID Connect supplies the identity layer.
- Mobile, browser, and backend clients need scoped API access with explicit expiration and renewal rules.
- An integration must keep accessing an API after the user leaves, making refresh-token storage and revocation part of the design.
- Services need tokens for their own identities, making the client credentials flow relevant rather than a browser redirect flow.
How to bring it up in the interview
- First clarify whether the requirement is login, delegated API access, or service-to-service access; these lead to different flows and token types.
- Draw the browser redirects separately from the token exchange, and name which component stores each credential.
- Propose authorization code with PKCE for user-facing clients, exact registered redirect URI matching, and request-bound state; expect questions about intercepted codes and login CSRF.
- Explain where token validation happens and where object-level authorization happens; a valid token with a read scope does not grant access to every user’s records.
- State a concrete revocation bound and failure policy, then defend token lifetime, introspection caching, signing-key rotation, and behavior during authorization-server outages.
Common mistakes
- Calling OAuth 2.0 an authentication protocol or using an access token as proof of login instead of using OpenID Connect.
- Assuming every OAuth token is a JWT, or sending an ID token to an API as though it were an access token.
- Embedding a client secret in a mobile app or browser bundle and treating it as confidential.
- Choosing implicit or password grants for a new design instead of authorization code with PKCE.
- Claiming that logout or refresh-token revocation immediately invalidates every already-issued access token.
Where it comes up
Interview questions where oauth 2.0 is part of a strong answer, and why.
Questions people ask
What is the difference between OAuth 2.0 and OpenID Connect?
OAuth 2.0 delegates access to APIs; it does not standardize how a client learns the authenticated user’s identity. OpenID Connect adds an identity layer, including an ID token, for login. Use access tokens for APIs and validate ID tokens for the client’s login flow.
How does the OAuth 2.0 authorization code flow work?
The client redirects the user to an authorization server, which authenticates the user and authorizes access. The browser returns a short-lived code, and the client exchanges that code for tokens. With PKCE, the exchange also requires a verifier that matches the challenge sent in the initial request, making an intercepted code insufficient by itself.
What is the difference between an access token and a refresh token?
An access token is presented to an API and grants limited access for a bounded time. A refresh token is presented to the authorization server to obtain new access tokens, not sent to resource APIs. Refresh tokens need stronger storage and lifecycle controls because they can extend access beyond one access token’s lifetime.