OAuth2 Primer For Frontend and Backend Developers
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.
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.