Skip to content

Instantly share code, notes, and snippets.

@iamucil
Last active November 15, 2021 11:47
Show Gist options
  • Save iamucil/21ee67b08ff93232cda9f626d0b5dad8 to your computer and use it in GitHub Desktop.
Save iamucil/21ee67b08ff93232cda9f626d0b5dad8 to your computer and use it in GitHub Desktop.
Postman Pre-Request script to generate JWT token from request body.
/*
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);
// 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);
var hashBase64Encoded = CryptoJS.enc.Base64.stringify(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);
// 1. Base64 encode the header
var encodedHeader = toBase64UrlEncoded(originalHeader);
// 2. Base64 encode the payload
var encodedPayload = toBase64UrlEncoded(originalPayload);
const originalSecret = secret.trim();
// 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 requestMethod = pm.request.method.toUpperCase();
const header = {
'alg': 'HS256',
'typ': 'JWT',
'method': requestMethod
};
var now = (new Date()).getTime();
var exp = now + 5000;
const apiKey = pm.environment.get('MERCHANT_KEY');
const apiSecret = pm.environment.get('MERCHANT_SECRET');
if (isNullOrEmpty(apiKey)) {
throw new Error("Entity values do not match");
}
if (isNullOrEmpty(apiSecret)) {
throw new Error("Entity values do not match");
}
const secretToken = apiKey + ':' + apiSecret;
log("secret >> " + secretToken);
/**
* Inside the payload, the keys of the object are claims.
* Registered claims is from request body (payload) which is json request
*/
let requestData = pm.request.body;
if (requestData == '') {
var payload = {
// retrieves the Zoom API key using the environment variable for this collection
'iss': apiKey.trim(),
'exp': exp,
'iat': now
};
} else {
var payload = JSON.parse(pm.request.body);
}
/**
* Generates the JWT
*/
var jwt = generateJWT(header, payload, secretToken);
// retrieves the 'apiToken' variable from the collection
pm.variables.set('apiToken', jwt);
log('jwt: ' + jwt);
@iamucil
Copy link
Author

iamucil commented Aug 4, 2021

  1. Put this script into Pre Request Script Tab
  2. Make sure you have body payload as raw json (even the request method is GET)
  3. Load variable apiToken into headers tab with curly bracket {{apiToken}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment