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
The code verifier string (43-128 characters)
Base64URL-encoded SHA256 hash of the code verifier
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 of verifier (must be between 43 and 128)
Returns
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
Returns
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().
Base64URL-encoded SHA256 hash of the code verifier
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'
})
});