PassKit v4 Token

Sample code to generate a PassKit v4 token

by pkosterman

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Base64/1.1.0/base64.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-sha256/0.9.0/sha256.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
<div class="container">
  <h2>This is an example token</h2>
  <p>
    Authenticate Passkit v4 Api Requests with:
  </p>
  <pre id="authToken" style="word-wrap: break-word;"></pre>
  <p>
    <a alt="Debug Token" id="debugLink" target="_blank"><img alt="Debug Token" src="http://jwt.io/img/logo-asset.svg"></a>
  </p>
  <p>
    Please note that this should only ever be used in backend servers, as storing your api_secret in frontend javascript code would reveal it to the public.
  </p>
  <p>
    More info on JWT <a href="https://auth0.com/learn/json-web-tokens/">here</a>
  </p>
</div>

JavaScript

// Short script to generate a basic jwt token and display it in the paragraph "authToken"

// Generates the jwt token from an api key and secret
var token = generateJWT("YOUR_API_KEY", "YOUR_API_SECRET");

// The Authorisation header of the HTTP request contains "PKAuth " + token string
document.getElementById("authToken").innerHTML = token;
  // I replaced the space with a non breaking space purely for format reasons.
document.getElementById("debugLink").href = "https://jwt.io/#id_token=" + token

function generateJWT(key, secret) {		
    var body = {
        "uid": key,
        "exp": Math.floor(new Date().getTime() / 1000) + 3600,
        "iat": Math.floor(new Date().getTime() / 1000),
        "web": true,
    };

    header = {
        "alg": "HS256",
        "typ": "JWT"
    };
    var token = [];
    token[0] = base64url(JSON.stringify(header));
    token[1] = base64url(JSON.stringify(body));
    token[2] = genTokenSign(token, secret);

   return token.join(".");
}

function genTokenSign(token, secret) {
    if (token.length != 2) {
        return;
    }
    var hash = CryptoJS.HmacSHA256(token.join("."), secret);
    var base64Hash = CryptoJS.enc.Base64.stringify(hash);
    return urlConvertBase64(base64Hash);
}


function base64url(input) {
    var base64String = btoa(input);
    return urlConvertBase64(base64String);
}

function urlConvertBase64(input) {
    var output = input.replace(/=+$/, '');
    output = output.replace(/\+/g, '-');
    output = output.replace(/\//g, '_');

   return output;
}