Skip to content

Instantly share code, notes, and snippets.

@mikecabana
Last active March 3, 2022 12:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mikecabana/9cae8b447afd2a36da5d38b94bfc2565 to your computer and use it in GitHub Desktop.
Save mikecabana/9cae8b447afd2a36da5d38b94bfc2565 to your computer and use it in GitHub Desktop.
Sample code_verifier and code_challenge generators for OAuth PKCE + Code Flow
/**
* Based on spec: https://tools.ietf.org/html/rfc7636#section-4
* Uses: https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js
*/
/**
*
* Static values
*
*/
const allowedCharacters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_~.';
/**
*
* Helpers
*
*/
const randomString = (length) => {
let result = '';
for (let i = 0; i < length; i++) {
result += allowedCharacters.charAt(Math.floor(Math.random() * allowedCharacters.length));
}
return result;
};
const base64encode = (value) =>
value.toString(CryptoJS.enc.Base64).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
const clearStorage = () => localStorage.clear();
/**
*
* API
*
*/
const generateCodeVerifier = (length) => {
if (length < 43 || length > 128) {
throw new Error('Code verifier length must be more than 42 and less than 129.');
}
return randomString(128);
};
const generateCodeChallenge = (data, transformation = 'S256') => {
if (transformation === 'plain') {
console.warn('It is not recommended to use a "plain" transformation.');
return data;
}
return base64encode(CryptoJS.SHA256(data));
};
/**
*
* Main
*
*/
(() => {
const code_verifier = generateCodeVerifier(128);
const code_challenge_plain = generateCodeChallenge(code_verifier, 'plain');
const code_challenge_s256 = generateCodeChallenge(code_verifier);
console.log({ code_verifier });
console.log({ code_challenge_plain });
console.log({ code_challenge_s256 });
localStorage.setItem('oidc', JSON.stringify({ code_verifier }));
alert(`code_verifier ${code_verifier} set in storage. Will clear in 15 seconds.`);
setTimeout(clearStorage, 15000);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment