Last active
April 22, 2024 03:34
-
-
Save tap52384/a9c27ab7fce292389b86bd00530ea536 to your computer and use it in GitHub Desktop.
Pre-Request Script for Generating JWTs (Postman)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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