JWT example

by Richard Hunter

JavaScript

const SECRET = 'open sesame';

function encode(json) {
  return btoa(JSON.stringify(json));
}

function decode(encoded) {
  return JSON.parse(atob(encoded));
}

function buildSignature(header, payload, secret) {
  return sha(`${encode(header)}.${encode(payload)}${secret}`);
}

function buildJWT(header, payload, secret) {
  return buildSignature(header, payload, secret).then(signature => {
    return `${encode(header)}.${encode(payload)}.${hexString(signature)}`;
  });
}

function authenticateJWT(jwt, secret) {
  const parts = jwt.split('.');
  const header = decode(parts[0]);
  const payload = decode(parts[1]);
  const signature = parts[2];
  
  buildSignature(header, payload, secret).then(result => {
  	console.log(hexString(result) === signature);
  });
}



const header = {
  "alg": "HS256",
  "typ": "JWT",
};

const payload = {
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
};

buildJWT(header, payload, SECRET).then(jwt => {
  plainText(jwt);
  //  prints true if second parameter is secret used to generate JWT
  authenticateJWT(jwt, 'open same');
});


function sha(message) {
  const encoder = new TextEncoder();
  const data = encoder.encode(message);
  return window.crypto.subtle.digest('SHA-256', data);
}

function hexString(buffer) {
  const byteArray = new Uint8Array(buffer);

  const hexCodes = [...byteArray].map(value => {
    const hexCode = value.toString(16);
    const paddedHexCode = hexCode.padStart(2, '0');
    return paddedHexCode;
  });

  return hexCodes.join('');
}

function plainText(jwt) {
	const parts = jwt.split('.');
	const header = decode(parts[0]);
  const payload = decode(parts[1]);
  const signature = parts[2];
  console.log('Plain text JWT');
  console.dir({ header, payload, signature });
}