ndovu oauth2 minisite

SPEC PRIMER · RFC 6749

The authorization-code grant

A plain-English walkthrough of the OAuth2 authorization-code grant from RFC 6749: the four roles, the ten steps on the wire, and why the code exchange exists at all.

October 24, 2026Try it: PKCE playground
01

What RFC 6749 is

Published in 2012, RFC 6749 is the document that defines OAuth 2.0: a delegation framework that lets an application obtain limited access to a user's resources on another service, without ever seeing the user's password. It specifies four ways to get an access token (grant types), of which the authorization code grant is the one used by virtually everything you log into: web apps, SPAs via PKCE, and native apps via RFC 8252.

The core idea: instead of handing your credentials to the application, you authenticate directly with the service that holds the data. That service then issues the application a short-lived access token scoped to exactly what you approved.

02

The four roles

RoleWho it isExample
Resource ownerThe user who owns the data and can grant access.You, approving a login screen
ClientThe application asking for access on the user's behalf.A newsletter dashboard
Authorization serverAuthenticates the user and issues tokens.accounts.google.com
Resource serverHosts the protected data and validates access tokens.gmail API endpoints
03

The flow, step by step

  1. The client sends the browser to the authorization server's authorize endpoint with response_type=code, its client_id, a redirect_uri, the requested scope, and a random state value.
  2. The authorization server shows a login and consent screen.
  3. The user authenticates and approves (or denies) the scopes.
  4. The authorization server redirects back to the client's redirect_uri with a one-time code and echoes state so the client can detect forged callbacks.
  5. The browser follows the redirect; the code lands on the client's callback.
  6. The client's backend exchanges the code at the token endpoint, authenticating itself with its client_secret (or PKCE when it has no secret).
  7. The authorization server validates everything and returns an access_token (usually with a refresh_token).
  8. The client calls the resource server with Authorization: Bearer the access token.
  9. The resource server validates the token and returns the protected data.
  10. The client renders the page. The token never touched the browser.
Authorization code flow sequence diagramBrowserWeb appAuth serverAPI1. GET /authorize (response_type=code)2. login + consent3. user signs in, approves scopes4. 302 redirect_uri?code=... (state)5. code hits callback6. POST /token (code + client auth)7. access_token (+ refresh)8. Authorization: Bearer ...9. protected resource10. rendered page
04

Why a code at all?

The obvious question: why not just return the access token in the redirect (the old implicit flow did exactly that)? Because the code is the only piece that passes through the browser, and it is deliberately useless on its own. Step 6 requires client authentication over a back channel, so a code leaked via referrer headers, browser history, or logs cannot be redeemed by an attacker.

Next in this minisite

SPAs and native apps cannot keep a client_secret, so step 6 authenticates the client differently: with PKCE (RFC 7636), a proof-key handshake you can try right now in thePKCE playground.

05

Primary sources