Skip to content

Instantly share code, notes, and snippets.

@velizarn
Last active August 3, 2026 11:52
Show Gist options
  • Select an option

  • Save velizarn/cd8a85c90d7e2ed08670ce6c341622b9 to your computer and use it in GitHub Desktop.

Select an option

Save velizarn/cd8a85c90d7e2ed08670ce6c341622b9 to your computer and use it in GitHub Desktop.
Verify Yubico OTP

Postman request

GET https://api.yubico.com/wsapi/2.0/verify?otp=__YOUR_YUBICO_OTP__

Pre-request script

const crypto = require('crypto-js'),
  yubiId = pm.variables.get('YUBI_ID'),
  yubiKey = pm.variables.get('YUBI_KEY'),
  secretKey = crypto.enc.Base64.parse(yubiKey),
  generatedNonce = crypto.lib.WordArray.random(10).toString(crypto.enc.Hex);

pm.request.url.query.upsert({ key: 'id', value: yubiId });
pm.request.url.query.upsert({ key: 'nonce', value: generatedNonce });

/**
 * Convert the Postman PropertyList to a standard JS Array
 * in order to avoid error:
 * "TypeError: queryParams.sort is not a function"
 * because pm.request.url.query is not a standard JavaScript array.
 * It is a Postman-specific object called a PropertyList
 */
const queryParams = pm.request.url.query.all();

const result = queryParams
  .filter(p => p.key && p.value && p.key !== 'h')
  .sort((a, b) => (a.key < b.key ? -1 : (a.key > b.key ? 1 : 0)))
  .map(item => `${item.key}=${item.value}`)
  .join('&');

const hash = crypto.HmacSHA1(result, secretKey);

const signature = hash.toString(crypto.enc.Base64);

pm.request.url.query.upsert({ key: 'h', value: signature });

console.clear();
console.log(result, signature);

Post-response script

const responseText = pm.response.text(),
  parsedResponse = {},
  otpReq = pm.request.url.query.get('otp');  

// Split by newlines (\r\n or \n) after trimming any outer spacing
responseText.trim().split(/\r?\n/).forEach(line => {
    if (!line) return; // Skip any accidental empty lines
    const parts = line.split('='); // Split by '='
    // Grab the very first item as the key
    const key = parts.shift().trim();
    // Re-join the rest with '=' in case the value contained an '=' (like Base64 'h')
    const value = parts.join('=').trim();
    parsedResponse[key] = value;
});

const otpResp = parsedResponse.otp || '';

pm.test('Status code is 200', () => pm.response.code === 200);

pm.test(`OTP is the same provided in the request: ${otpReq}`, function () {
    pm.expect(otpResp).to.eql(otpReq);
});

pm.test('OTP Status should be OK', function () {
    pm.expect(parsedResponse.status).to.eql('OK');
});

Resources

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