OAuth2 is an open standard for authorization. RFC 6749 defines the standard. It allows an application to obtain limited access to a resource on behalf of a user or another application. OAuth2 defines several authorization flows. Each flow applies to a different use case. This document describes four major OAuth2 flows.

  1. Authorization Code Flow
  2. Client Credentials Flow
  3. Device Authorization Flow
  4. Implicit Flow (Legacy)

Authorization Code Flow

The client application redirects the user to the authorization server. The user authenticates and gives consent. The authorization server returns an authorization code to the client. The client exchanges the code for an access token.

This flow is 3-legged. Use this flow for human-to-service access in stateful web applications that render all pages on the server. Do not use this flow for single-page applications such as those created with React.

sequenceDiagram
    participant User
    participant Client
    participant AuthServer as Authorization Server
    participant Resource as Resource Server

    User->>Client: Start login
    Client->>User: Redirect to AuthServer
    User->>AuthServer: Authenticate and consent
    AuthServer->>User: Redirect with authorization code
    User->>Client: Deliver code
    Client->>AuthServer: Exchange code + client secret for token
    AuthServer->>Client: Return access token (+ refresh token)
    Client->>Resource: Request with access token
    Resource->>Client: Return protected data

The client must keep the client secret private. The application must maintain server-side session state. Always use HTTPS.

Authorization Code Flow with PKCE

The client creates a random code verifier and a code challenge. The client sends the code challenge with the authorization request. After the user consents, the client sends the code verifier with the token request. The authorization server verifies the challenge and returns the access token.

This flow is 3-legged. Use this flow for human-to-service access in public clients such as single-page applications created with React and mobile apps.

sequenceDiagram
    participant User
    participant Client
    participant AuthServer as Authorization Server
    participant Resource as Resource Server

    Client->>Client: Generate code verifier and challenge
    User->>Client: Start login
    Client->>User: Redirect to AuthServer with challenge
    User->>AuthServer: Authenticate and consent
    AuthServer->>User: Redirect with authorization code
    User->>Client: Deliver code
    Client->>AuthServer: Exchange code + verifier for token
    AuthServer->>Client: Return access token (+ refresh token)
    Client->>Resource: Request with access token
    Resource->>Client: Return protected data
How PKCE Protects Against Code Theft

PKCE binds the authorization code to the specific client instance that started the request. The client keeps the code verifier in memory. The client never sends the verifier in the initial redirect. An attacker who views the page source, inspects network traffic, or captures the redirect URL obtains only the authorization code. The attacker cannot exchange that code for an access token or refresh token. The attacker lacks the matching code verifier. The authorization server rejects the token request. This stops the attacker from using the stolen code in another application.

PKCE protects against authorization code interception. Use PKCE for all public clients. Do not store long-lived secrets in the client. Store tokens in memory when possible. Do not place tokens in local storage if XSS is a risk.

Client Credentials Flow

The client authenticates directly to the authorization server with its client ID and client secret. The authorization server returns an access token. No user is involved.

This flow is 2-legged. Use this flow for service-to-service access where one application accesses resources of another application.

sequenceDiagram
    participant Client
    participant AuthServer as Authorization Server
    participant Resource as Resource Server

    Client->>AuthServer: Authenticate with client ID and secret
    AuthServer->>Client: Return access token
    Client->>Resource: Request with access token
    Resource->>Client: Return protected data

The client must protect the client secret. This flow does not support user context or refresh tokens in most implementations. Limit the token scope to the minimum required permissions.

Device Authorization Flow

The client requests a device code and user code from the authorization server. The user opens a browser on another device, enters the user code, and gives consent. The client polls the authorization server until it receives the access token.

This flow is 3-legged. Use this flow for human-to-service access on devices with limited input such as smart TVs or CLI tools.

sequenceDiagram
    participant User
    participant Device as Client Device
    participant Browser
    participant AuthServer as Authorization Server
    participant Resource as Resource Server

    Device->>AuthServer: Request device code
    AuthServer->>Device: Return device code + user code + verification URI
    Device->>User: Display user code and URI
    User->>Browser: Open verification URI
    Browser->>AuthServer: Enter user code and consent
    loop Poll
        Device->>AuthServer: Check status with device code
        AuthServer->>Device: Pending or token
    end
    AuthServer->>Device: Return access token (+ refresh token)
    Device->>Resource: Request with access token
    Resource->>Device: Return protected data

The user must have access to a separate browser. Polling must use exponential back-off. The authorization server limits the lifetime of the device code.

Implicit Flow (Legacy)

The client redirects the user to the authorization server. After consent, the authorization server redirects the user back to the client with the access token in the URL fragment. The client extracts the token directly from the browser.

This flow is 3-legged. Historically used for human-to-service access in browser-only applications.

sequenceDiagram
    participant User
    participant Client
    participant AuthServer as Authorization Server
    participant Resource as Resource Server

    User->>Client: Start login
    Client->>User: Redirect to AuthServer
    User->>AuthServer: Authenticate and consent
    AuthServer->>User: Redirect with access token in fragment
    User->>Client: Deliver token (via browser)
    Client->>Resource: Request with access token
    Resource->>Client: Return protected data

Do not use this flow in new applications. The token is exposed in the browser history and referrer headers. Use Authorization Code Flow with PKCE instead. Many authorization servers have disabled this flow.