OAuth

Authorization Code vs Client Credentials — When to Use Each

The most common OAuth mistake is using the wrong grant type. Authorization Code + PKCE is for when a user is present and authorizing your app. Client Credentials is for server-to-server calls with no user involved.

Authorization Code + PKCE — user present

Use this when a human user needs to grant your app access to their account on another service.

// Typical use cases:
// - "Sign in with Google"
// - "Connect your Slack workspace"
// - "Allow access to your GitHub repos"
// - Any flow where the user must approve access

Client Credentials — no user, machine-to-machine

Use this for server-to-server API calls where there is no user involved. Your server authenticates directly with the auth server using its own credentials.

// POST directly to the token endpoint
const response = await fetch('https://auth.example.com/token', {
  method: 'POST',
  body: new URLSearchParams({
    grant_type: 'client_credentials',
    client_id: 'YOUR_CLIENT_ID',
    client_secret: 'YOUR_CLIENT_SECRET',
    scope: 'read:data write:data',
  })
});

// Use the access token for API calls
const { access_token } = await response.json();

Other flows and when they apply

FlowWhen to use
Authorization Code + PKCESPAs, mobile apps, any user-facing flow
Client CredentialsServer-to-server, background jobs, microservices
Device CodeTVs, CLI tools, devices with no browser
Refresh TokenNot a standalone flow — used with Authorization Code to get new access tokens

Never use Implicit Flow

Implicit Flow (response_type=token) was deprecated in OAuth 2.1. It returns tokens in the URL fragment — which gets logged in browser history, server logs, and can be stolen by referrer headers. Always use Authorization Code + PKCE for SPAs instead.

Debug your OAuth errors → OAuthFixer