Skip to content

Instantly share code, notes, and snippets.

@tap52384
Last active August 23, 2023 16:44
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tap52384/a9c27ab7fce292389b86bd00530ea536 to your computer and use it in GitHub Desktop.
Save tap52384/a9c27ab7fce292389b86bd00530ea536 to your computer and use it in GitHub Desktop.
Pre-Request Script for Generating JWTs (Postman)
/*
https://jwt.io/introduction/
In its compact form, JSON Web Tokens consist of three parts separated by dots (.), which are:
Header
Payload
Signature
Therefore, a JWT typically looks like the following.
xxxxx.yyyyy.zzzzz
Within Postman, this script has no dependencies.
*/
function isNullOrEmpty ( x ) {
return x === undefined || x === '' || x === null || typeof x === 'undefined';
}
function isNullOrEmptySpace( x ) {
return isNullOrEmpty( x ) || typeof x.trim === 'function' &&
isNullOrEmpty( x.trim().replace( / /g, '' ) );
}
function isValidStringObject( s ) {
return isNullOrEmpty( s ) === false &&
Object.prototype.toString.call( s ) === '[object String]';
}
/**
* A function for logging that is browser-friendly and node.js-friendly.
* @param {string|object} text The text or object to be logged to the console.
* @param {boolean} error If true, the text is logged as an error.
* @return {void}
*/
function log( text, error ) {
if ( isNullOrEmptySpace( text ) ) {
return;
}
// 2015.03.04 - if the parameter is not a string, then break down what it is
if ( isValidStringObject( text ) === false ) {
text = JSON.stringify( text );
}
if ( typeof window !== 'undefined' && window.console ) {
if ( error && window.console.error ) {
window.console.error( text );
} else if ( window.console.log ) {
window.console.log( text );
}
} else if ( typeof document !== 'undefined' && document.console ) {
if ( error && document.console.error ) {
document.console.error( text );
} else if ( document.console.log ) {
document.console.log( text );
}
} else if ( console ) {
if ( error && console.error ) {
console.error( text );
} else if ( console.log ) {
console.log( text );
}
}
}
function cleanBase64( input ) {
if ( isNullOrEmptySpace( input ) === true ) {
return '';
}
return input.replace(/=+$/, '').replace(/\+/g, '-').replace(/\//g, '_');
}
/**
* Base64-encoded the given string. For the header and payload, make
* sure that JSON.stringify() was called first.
* @param {string} input JSON-encoded string to encode via base64.
* @return {string} A base64-encoded JSON string with certain characters replaced for compatibility.
*/
function toBase64UrlEncoded( input ) {
// 1. Convert the variable to base64
// btoa - binary data to base64-encoded ascii
// https://www.npmjs.com/package/btoa
var converted = btoa( input );
log( 'input: ' + input );
log( 'converted: ' + converted );
// 2. Clean the converted input of invalid characters
return cleanBase64( converted );
}
/**
* Creates the signature of the JWT.
* @param {object} encodedHeader Base64-encoded header string.
* @param {object} encodedPayload Base64-encoded payload string.
* @param {string} secret The API secret from Zoom.
* @return {string} The JWT signature.
*/
function createSignature( encodedHeader, encodedPayload, secret ) {
if ( isNullOrEmptySpace( encodedHeader ) === true ||
isNullOrEmptySpace( encodedPayload ) === true ||
isNullOrEmptySpace( secret ) === true ) {
log( 'signature could not be created due to missing JWT part')
return '';
}
var hash = CryptoJS.HmacSHA256( ( encodedHeader + '.' + encodedPayload ), secret );
log( 'hash: ' + hash );
var hashBase64Encoded = CryptoJS.enc.Base64.stringify( hash );
log( 'base64-encoded hash:' + hash );
var hashCleaned = cleanBase64( hashBase64Encoded );
return hashCleaned;
}
/**
* Creates a JWT from a header object, payload object, and an API secret.
* Was created with Zoom (zoom.us) in mind.
* @param {object} header
* @param {object} payload
* @param {string} secret The API secret from Zoom.
* @return {string} The JWT token.
*/
function generateJWT( header, payload, secret ) {
const originalHeader = JSON.stringify( header );
const originalPayload = JSON.stringify( payload );
log( 'api key: ' + pm.variables.get( 'apiKey' ) );
// 1. Base64 encode the header
var encodedHeader = toBase64UrlEncoded( originalHeader );
// 2. Base64 encode the payload
var encodedPayload = toBase64UrlEncoded( originalPayload );
log( 'encoded header: ' + encodedHeader );
log( 'encoded payload: ' + encodedPayload );
const originalSecret = secret.trim();
log( 'api secret: ' + secret );
// 3. Use the encoded header and payload along with the secret to
// create the signature
var signature = createSignature(
encodedHeader,
encodedPayload,
originalSecret
);
// 4. Return them combined.
return encodedHeader + '.' + encodedPayload + '.' + signature;
}
var now = (new Date()).getTime();
var exp = now + 5000;
const header = {
'alg': 'HS256',
'typ': 'JWT'
};
/**
* Inside the payload, the keys of the object are claims.
* Registered claims (exp, iat, iss, aud) are no more than three characters long.
*/
const payload = {
// retrieves the Zoom API key using the environment variable for this collection
'iss': pm.variables.get( 'apiKey' ).trim(),
'exp': exp,
'iat': now
};
/**
* Generates the JWT
*/
var jwt = generateJWT( header, payload, pm.variables.get( 'apiSecret' ) );
// retrieves the 'apiToken' variable from the collection
pm.variables.set( 'apiToken', jwt );
log( 'jwt: ' + jwt );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment