Skip to main content

PKCE

PKCE (Proof Key for Code Exchange) utilities for OAuth 2.0 public clients. Implements RFC 7636 for secure authorization code exchange without a client secret. Used by Electron apps, React Native/mobile apps, CLI tools, and other public clients.

Installation

import { PKCE } from '@workos-inc/node';

const pkce = new PKCE();

Methods

generate()

Generate a complete PKCE pair (verifier + challenge). Returns
codeVerifier
string
required
The code verifier string (43-128 characters)
codeChallenge
string
required
Base64URL-encoded SHA256 hash of the code verifier
codeChallengeMethod
'S256'
required
The code challenge method (always ‘S256’)
Example
const pkce = new PKCE();
const { codeVerifier, codeChallenge, codeChallengeMethod } = await pkce.generate();

console.log(codeVerifier); // "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
console.log(codeChallenge); // "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"
console.log(codeChallengeMethod); // "S256"

generateCodeVerifier()

Generate a cryptographically random code verifier. Parameters
length
number
default:43
Length of verifier (must be between 43 and 128)
Returns
verifier
string
RFC 7636 compliant code verifier
Example
const pkce = new PKCE();
const verifier = pkce.generateCodeVerifier();

console.log(verifier); // "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

// Custom length
const longVerifier = pkce.generateCodeVerifier(128);
Errors Throws RangeError if length is less than 43 or greater than 128.

generateCodeChallenge()

Generate S256 code challenge from a verifier. Parameters
verifier
string
required
The code verifier string
Returns
challenge
string
Base64URL-encoded SHA256 hash of the verifier
Example
const pkce = new PKCE();
const verifier = pkce.generateCodeVerifier();
const challenge = await pkce.generateCodeChallenge(verifier);

console.log(challenge); // "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"

Types

PKCEPair

The complete PKCE pair returned by generate().
codeVerifier
string
required
The code verifier string
codeChallenge
string
required
Base64URL-encoded SHA256 hash of the code verifier
codeChallengeMethod
'S256'
required
The code challenge method (always ‘S256’)

OAuth 2.0 Flow

Use PKCE in your OAuth 2.0 authorization flow:
const pkce = new PKCE();
const { codeVerifier, codeChallenge } = await pkce.generate();

// Step 1: Store the code verifier securely
sessionStorage.setItem('code_verifier', codeVerifier);

// Step 2: Redirect to authorization URL with code challenge
const authUrl = `https://api.workos.com/oauth/authorize?` +
  `client_id=YOUR_CLIENT_ID&` +
  `response_type=code&` +
  `code_challenge=${codeChallenge}&` +
  `code_challenge_method=S256`;

window.location.href = authUrl;

// Step 3: After redirect, exchange code with verifier
const code = new URLSearchParams(window.location.search).get('code');
const storedVerifier = sessionStorage.getItem('code_verifier');

const response = await fetch('https://api.workos.com/oauth/token', {
  method: 'POST',
  body: JSON.stringify({
    client_id: 'YOUR_CLIENT_ID',
    code: code,
    code_verifier: storedVerifier,
    grant_type: 'authorization_code'
  })
});

Build docs developers (and LLMs) love