OAuth 2.0 Authorization Code Flow with PKCE

Auth & Payment Flows · sequence diagram · CC0-1.0

Sequence diagram of the OAuth 2.0 Authorization Code flow with PKCE — the recommended pattern for SPAs, mobile apps, and any public client that cannot keep a secret.

Source: https://datatracker.ietf.org/doc/html/rfc7636
Curated by Archigram editorial
oauth auth pkce openid-connect security

Mermaid source

sequenceDiagram
    autonumber
    participant U as User
    participant C as Client App
    participant A as Authorization Server
    participant R as Resource Server

    U->>C: Click "Sign in"
    C->>C: Generate code_verifier + code_challenge
    C->>A: GET /authorize?response_type=code&code_challenge&...
    A->>U: Show login + consent
    U->>A: Approve
    A-->>C: 302 redirect with auth_code
    C->>A: POST /token (auth_code + code_verifier)
    A->>A: Verify PKCE challenge
    A-->>C: { access_token, refresh_token, id_token }
    C->>R: GET /api/me  (Bearer access_token)
    R-->>C: 200 user profile JSON
    Note over C,A: Refresh: POST /token grant_type=refresh_token

What this diagram shows

Step-by-step interaction between the user, client app, authorization server, and resource server during an OAuth 2.0 sign-in. The client generates a PKCE code_verifier and a derived code_challenge, redirects the user to /authorize, and after consent receives a short-lived authorization code. It exchanges the code (plus the original code_verifier) for tokens at /token; the auth server verifies the PKCE challenge before issuing an access token, refresh token, and OIDC id_token. The client then calls a protected resource as a Bearer.

When to use it

This is the modern default for any new OAuth integration. PKCE makes the flow safe even for public clients (SPAs, mobile, CLIs) that cannot keep a client secret confidential. Use it whenever the client can perform a redirect — almost always preferred over the older Implicit flow (now deprecated) and the Resource Owner Password Credentials grant (which leaks the user password to the client).

How to adapt it for your project

For confidential server-side clients, you can keep the PKCE step (defense in depth) and additionally include the client_secret on the token request. For machine-to-machine flows where there is no user, switch to the Client Credentials grant (a much shorter sequence). For step-up auth, add an acr_values parameter to the /authorize call and prompt the user for a stronger factor. If you need offline access, request the offline_access scope and persist the refresh token in the browser via httpOnly cookie or in secure mobile storage.

Key concepts

Related diagrams