Last Updated: Jul 26, 2026

The OAuth 2.0 Authorization Code Flow, Explained

The OAuth 2.0 authorization code flow explained. How the redirect and code exchange work step by step, why PKCE is the default, when to use it, and mistakes to avoid.
The OAuth 2.0 Authorization Code Flow, Explained

The OAuth 2.0 authorization code flow is the method an application uses to get an access token when a real user is signing in. The user authenticates at a trusted provider, the application receives a short-lived one-time code, and it exchanges that code for a token over a secure back channel. It is the flow behind almost every "Sign in with" button and third-party connection you have ever approved.

This is the one flow most developers should learn first, because it is the recommended default for web apps, mobile apps, and single-page apps, and because getting it right closes off a whole category of token-theft bugs. This guide walks through what it is, how it works step by step, why PKCE is now part of it, when to use it, and the mistakes worth avoiding. For the wider picture of OAuth and its other flows, start with What is OAuth 2.0.

Why is the authorization code flow the default?

The authorization code flow is the default because it keeps tokens out of the browser and off the address bar. The application never sees the user's password, and the access token is delivered over a direct server-to-server call rather than through the redirect the user's browser can see. That separation is what makes it the recommended choice for any app where a user is present, and it is the flow OAuth 2.1 pushes everyone toward.

The contrast is the older implicit flow, which returned tokens directly in the browser redirect where scripts and browser history could reach them. Current guidance discourages it for exactly that reason. The authorization code flow avoids the problem by handing back a temporary code first, and only trading that code for a real token in a place the browser cannot observe.

How does the authorization code flow work, step by step?

The flow is a sequence of redirects and one back-channel exchange. Five steps cover it end to end:

  1. The app sends the user to the authorization server. When the user clicks sign in, the app redirects them to the provider with a request that names the app (its client ID), where to return the user (the redirect URI), what access it wants (the scope), and a random state value to tie the response back to this request.
  2. The user authenticates and approves. The authorization server, not the app, collects the user's login and shows the consent screen. The app never touches the password.
  3. The server returns a one-time code. The authorization server redirects the user back to the app's redirect URI carrying a short-lived authorization code and the same state value. This code is not a token and cannot call any API on its own.
  4. The app exchanges the code for tokens. Now on the back channel, server to server, the app sends the code to the token endpoint along with proof it is the same app that started the flow. The server returns an access token, and often a refresh token.
  5. The app calls the API. The app attaches the access token to its API requests, and the resource server validates the token and allows or rejects each call.

The point of the two-step handoff, a code first and a token second, is that the only value the browser ever sees is a one-time code that is useless without the back-channel exchange in step four.

What is PKCE, and why does the flow need it?

PKCE, Proof Key for Code Exchange, is an add-on that binds the token exchange to the app that started the flow, so a stolen authorization code cannot be redeemed by anyone else. It is defined in RFC 7636, and it is now the recommended default for every client using this flow, not just mobile apps.

It works with a secret the app generates for each flow. At step one, the app creates a random value called the code verifier, hashes it into a code challenge, and sends only the challenge. At step four, when it exchanges the code for a token, it must present the original verifier. The authorization server hashes that verifier and checks it against the challenge it saw earlier. If an attacker intercepts the authorization code in step three, they still cannot complete step four, because they never had the verifier. PKCE began as a safeguard for mobile and single-page apps that cannot keep a secret, and current guidance now applies it broadly. If you build this flow, build it with PKCE.

When should you use the authorization code flow?

Use the authorization code flow whenever a human is signing in: server-rendered web apps, mobile and native apps, and single-page apps. Public clients like mobile and single-page apps use it with PKCE and no client secret, because they cannot store a secret safely. Confidential clients like a traditional web server use it with both PKCE and a client secret.

It is the wrong flow when there is no user. A background job or a service calling another service authenticates as itself, which is the client credentials grant, not this one. Input-constrained devices like TVs use the device authorization flow instead. Matching the flow to the situation is the whole skill, and What is OAuth 2.0 lays out the full set.

What are the common mistakes with the authorization code flow?

A handful of errors show up again and again:

  • Skipping PKCE. Without it, an intercepted code can be redeemed by an attacker. There is no good reason to omit it now.
  • Not validating state. The state value defends against cross-site request forgery on the redirect. If the app does not check that the returned state matches the one it sent, it accepts responses it should reject.
  • Storing tokens in browser localStorage. Any cross-site scripting on the page can then read them. Server-side sessions and httpOnly cookies keep tokens out of reach of page scripts.
  • Treating a completed flow as proof of login. A successful authorization tells the app it was granted access, not who the user is. Proving identity is the job of OpenID Connect, covered in OpenID Connect vs OAuth 2.0.
  • Putting a client secret in a public client. Anything shipped to a browser or a phone can be extracted, so mobile and single-page apps rely on PKCE instead of a secret.

How does MonoCloud implement the authorization code flow?

MonoCloud is an OIDC-certified identity platform, so the authorization code flow with PKCE works out of the box for your web, mobile, and single-page apps, with the redirects, the code exchange, session handling, and token refresh handled for you. You configure the client and match the flow to it rather than assembling any of the steps above by hand.

What is worth calling out is the token exchange in step four. MonoCloud evaluates a policy before it issues an access token, deciding whether the token may be granted and what it carries, which turns the exchange from "hand back a token" into "decide access at the moment of issuance." You can see how that works in the API Access Policies guide, or start building on MonoCloud for free.