Skip to content

Instantly share code, notes, and snippets.

@Jamsek-m
Last active August 24, 2021 14:05
Show Gist options
  • Save Jamsek-m/3219334d383c3065c1f6839423b0291d to your computer and use it in GitHub Desktop.
Save Jamsek-m/3219334d383c3065c1f6839423b0291d to your computer and use it in GitHub Desktop.
Generating challenge for use with authorization code flow with PKCE (OpenID Connect) using browser Crypto API
function base64UrlEncode(str: string): string {
return btoa(str)
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/g, "");
}
function generateCodeVerifier(len: number): string {
const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let randomData = new Uint8Array(len);
window.crypto.getRandomValues(randomData);
let verifierCharacters = new Array(len);
for (let i = 0; i < verifierCharacters.length; i++) {
verifierCharacters[i] = ALPHABET.charCodeAt(randomData[i] % ALPHABET.length);
}
return String.fromCharCode.apply(null, verifierCharacters);
}
async function generatePkceChallenge(verifier: string, method: "S256" | "plain") {
if (method === "S256") {
let hashBytes = new TextEncoder().encode(verifier);
const digest = await window.crypto.subtle.digest("SHA-256", hashBytes);
return base64UrlEncode(String.fromCharCode(...new Uint8Array(digest)));
}
// If plain, verifier == challenge
return verifier;
}
const verifier = generateCodeVerifier(80); // length between 43 - 128
generatePkceChallenge(verifier, "S256").then(challenge => {
console.log(`Verifier: ${verifier}, Challenge: ${challenge}`);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment