Skip to content

Instantly share code, notes, and snippets.

@mquarters
Last active October 20, 2021 21:44
Show Gist options
  • Save mquarters/1db983b10dcddbca08227ef96afc52c0 to your computer and use it in GitHub Desktop.
Save mquarters/1db983b10dcddbca08227ef96afc52c0 to your computer and use it in GitHub Desktop.
Postman-hmac-authentication-v9
//Sign with Remote.it Http-Signature
const urlTool = require('url')
function computeHttpSignature(config, headerHash) {
let sig = 'Signature keyId="${keyId}",algorithm="${algorithm}",headers="${headers}",signature="${signature}"'
// compute sig here
let signingBase = ''
config.headers.forEach(function(h){
if (signingBase !== '') { signingBase += '\n' }
signingBase += h.toLowerCase() + ": " + headerHash[h]
})
const hashf = (function() {
switch (config.algorithm) {
case 'hmac-sha1': return CryptoJS.HmacSHA1
case 'hmac-sha256': return CryptoJS.HmacSHA256
case 'hmac-sha512': return CryptoJS.HmacSHA512
default : return null
}
}())
console.log(signingBase)
const hash = hashf(signingBase, config.secretkey)
const signatureOptions = {
keyId : config.keyId,
algorithm: config.algorithm,
headers: config.headers,
signature : CryptoJS.enc.Base64.stringify(hash)
}
// build sig string here
Object.keys(signatureOptions).forEach(function(key) {
var pattern = "${" + key + "}",
value = (typeof signatureOptions[key] != 'string') ? signatureOptions[key].join(' ') : signatureOptions[key]
sig = sig.replace(pattern, value)
})
return sig
}
//postman version 9.0.5 doesn't allow you get length of the body in all cases. Its dependent on the body 'mode' and computed at send request
function computeContentLength(mode, body){
switch (mode) {
case 'raw': {
if (body.raw == undefined) {
return 0
} else {
return Buffer.byteLength(body.raw)
}
}
case 'graphql': return Buffer.byteLength(getModifiedBody(body.graphql))
default : return 0
}
}
function getModifiedBody(body) {
let modifiedBody = {}
Object.keys(body).forEach(function (h) {
if (body[h] !== "" && body[h] !== 'undefined') modifiedBody[h]= body[h]
})
const modifiedBodyString = JSON.stringify(modifiedBody)
return modifiedBodyString
}
function replaceVariables(content) {
while(content.indexOf('{{') >= 0) {
const variableName = content.substring(content.indexOf('{{')+2, content.indexOf('}}'))
const variableValue= pm.environment.get(variableName) || pm.globals.get(variableName)
content = content.replace('{{'+variableName+'}}', variableValue)
}
return content
}
const url = replaceVariables(request.url)
const { hostname } = urlTool.parse(url)
const accessKey = pm.environment.get('R3_ACCESS_KEY_ID') || pm.globals.get('R3_ACCESS_KEY_ID')
const accessKeySecretPreParse = pm.environment.get("R3_SECRET_ACCESS_KEY") || pm.globals.get("R3_SECRET_ACCESS_KEY")
const accessKeySecret = CryptoJS.enc.Base64.parse(accessKeySecretPreParse)
const curDate = new Date().toGMTString()
const targetUrl = url.trim().replace(new RegExp('^https?://[^/]+/'),'/') // strip hostname
const method = request.method.toLowerCase()
const contentLength = computeContentLength(pm.request.body.mode, pm.request.body)
const contentType = 'application/json'
const headerHash = {
date : curDate,
'(request-target)' : method + ' ' + targetUrl,
'host' : hostname,
'content-type': contentType,
'content-length' : contentLength
}
const config = {
algorithm : 'hmac-sha256',
keyId : accessKey,
secretkey : accessKeySecret,
headers : [ '(request-target)', 'host','date', 'content-type', 'content-length' ]
}
const sig = computeHttpSignature(config, headerHash)
pm.request.headers.add({key: 'Authorization', value: sig})
pm.request.headers.add({key: 'Date', value: curDate})
pm.request.headers.add({key: 'content-length', value: contentLength})
pm.request.headers.add({key: 'content-type', value: contentType})
pm.request.headers.add({key: 'developerkey', value: '{{R3_DEVELOPER_API_KEY}}' })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment