diagram.mmd — sequence
OAuth2 Authorization Code Flow sequence diagram

The OAuth2 Authorization Code Flow is the most secure and widely used OAuth2 grant type, designed for applications that can keep a client secret confidential — typically server-side web apps and backend services acting on behalf of a user.

The flow begins when a user initiates login. The client application redirects the browser to the authorization server with several query parameters: client_id to identify the app, redirect_uri specifying where to send the user after authorization, scope listing the requested permissions, state (a random nonce to prevent CSRF attacks), and response_type=code. The authorization server presents a login form and a consent screen describing what the app wants to access.

Once the user authenticates and approves, the authorization server redirects back to the client's redirect_uri with a short-lived authorization code in the query string. This code is single-use and typically expires in 60–600 seconds. Critically, the code is passed through the browser, so it is visible in browser history and logs — but it is useless without the client secret.

The client immediately exchanges the authorization code for tokens by making a back-channel POST to the /token endpoint, sending the code along with its client_id and client_secret. This server-to-server call is never visible to the browser. The authorization server validates the code and issues an access token (short-lived, used to call APIs) and a refresh token (long-lived, used to obtain new access tokens without re-prompting the user).

The client stores the tokens, then calls the resource server (your API) using the access token as a Bearer header. The resource server validates the token — either by introspection or by verifying its JWT signature — and returns the protected data.

This flow is the foundation for OpenID Connect Flow, which adds an id_token to carry user identity. For background services without user interaction, see OAuth2 Client Credentials Flow. Managing token lifetimes in production requires Refresh Token Rotation. The full access token lifecycle, including validation, is covered in JWT Authentication Flow.

Free online editor
Edit this diagram in Graphlet
Fork, modify, and export to SVG or PNG. No sign-up required.
Open in Graphlet →

Frequently asked questions

The OAuth2 Authorization Code Flow is a grant type where a user-facing client obtains an authorization code via a browser redirect, then exchanges that code for tokens in a secure back-channel request. It is designed for applications that can keep a client secret confidential, such as server-side web apps.
The client redirects the user to the authorization server with `response_type=code`, `client_id`, `redirect_uri`, `scope`, and `state`. After the user authenticates and consents, the server redirects back with a short-lived code. The client POSTs the code plus its `client_secret` to the `/token` endpoint and receives an access token and refresh token in return.
PKCE (Proof Key for Code Exchange) is an extension that protects the flow when a client secret cannot be kept confidential — for example in single-page apps or mobile apps. The client generates a `code_verifier`, hashes it to a `code_challenge`, and sends the challenge in the authorization request. The `/token` exchange includes the raw verifier, which the server hashes and compares to prevent authorization code interception attacks.
Use it whenever a human user is authenticating a client application that can protect a secret. For user-facing SPAs and mobile apps without a secure backend, add PKCE. For server-to-server calls without a user, use Client Credentials Flow instead.
The Implicit Flow returned tokens directly in the URL fragment, bypassing the back-channel exchange. It is now deprecated because tokens were exposed in browser history and referrer headers. The Authorization Code Flow (with PKCE for public clients) replaces it for all use cases.
mermaid
sequenceDiagram participant User participant Client as Client App participant AuthServer as Authorization Server participant ResourceServer as Resource Server User->>Client: Click "Login with Provider" Client->>AuthServer: Redirect with client_id, scope, redirect_uri, state AuthServer->>User: Show login and consent screen User->>AuthServer: Authenticate and approve scopes AuthServer->>Client: Redirect with authorization code Client->>AuthServer: POST /token with code + client_secret AuthServer-->>Client: Access token + refresh token Client->>ResourceServer: GET /api/user with Bearer token ResourceServer-->>Client: Protected resource data Client-->>User: Show user data
Copied to clipboard