Skip to content

Instantly share code, notes, and snippets.

@the-vampiire
Created July 24, 2019 00:19
Show Gist options
  • Select an option

  • Save the-vampiire/8ec171dee71f9812c38c4414826998ba to your computer and use it in GitHub Desktop.

Select an option

Save the-vampiire/8ec171dee71f9812c38c4414826998ba to your computer and use it in GitHub Desktop.
generate a usable object of jwt.kid:RSA entries for verifying AWS cognito tokens

generation

$ node index.js <AWS cognito user pool ID> <relative/output/path.js>

generates the following file shape

module.exports = {
  "xx5AUUrXtNALyVgnDsPerQMYNODhpD+tzYoTeqkuqE0=":
    "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp074sUOC4AvwLyjECa1B\nWMqoocp2Cgkd0qOCIJqa5XCRVKLdw4WYykANN7SlV9EnUhdSxBOdvHW0tKzvt6Uw\nR0J0HSYxF0xwpTO+539J+XjB6ywkUZYjACOCzT8tjK09VAP0iBiUhb+3phY4xE7X\noUgLyJumk8x8r5DdDLpuhuLvB5Lmo33PpeSakcHLopvYkL9p+8fbuF1/0odhJ4gp\nIfyKE2KnNYok1dG3mx5HaqNXyFLEG2NYt7zHDoCYXbvPAs5gPP7hANlVbsH0LQcQ\n1yVrq8DRzupTfvP8YgmbXXCZ0gzvGuktV2jYRVwS1wrrCIcd7IXad0vqRUulikNB\n5QIDAQAB\n-----END PUBLIC KEY-----\n",
  "gyYIJ8RlhYcFFiBBm1WDjOKd1yZGEUcKXaXO71zURsE=":
    "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAovxHEVtt0ALqWgRy/7sB\nzddP8NVbHw/GS5C+J70E5wxfp1DrRumLE4bT+GKIZWxYC/UFNwKz04WP9MTQZ+7K\nHCWEXayIxwqQmR+BAgjZVbRLxLTHrtmTzCHGx+v3opw8rRdfRbQ8mb6latSOtDEo\nDDs0qwJxfgMB+02fnzvuWf1SEX+fJhth3ayKvuVFjHqhg5n+mtgjYAV4LThiM8Ax\n5DqOFgOUlW/iB34vC3uaw2csi9ExGZgaypZ97SXBYcFJbSOkiRVTLOu/6UQm65TB\n1z3OYTTO8i0FFVPmltRrl/5ErF409ErbfXmIbxqwnUHKRzL2yZpA6+5WVqD1219W\ntQIDAQAB\n-----END PUBLIC KEY-----\n",
};

usage

const jwt = require("jsonwebtoken");
const pems = require("./output/file");

// source the token
const decodedToken = jwt.decode(token);

// extract the kid from the token header
const kid = decodedToken.header.kid;

// get the corresponding public signing key
const pem = pems[kid];

// verify the token
jwt.verify(token, pem, { /* additional claim checks */); // throws if fails
const fs = require("fs");
const jwkToPem = require("jwk-to-pem");
const axios = require("axios").default;
const generatePEMs = async () => {
const [userPoolId, relativeOutPath] = process.argv.slice(2);
const [region] = userPoolId.split("_");
const url = `https://cognito-idp.${region}.amazonaws.com/${userPoolId}/.well-known/jwks.json`;
const res = await axios.get(url);
const PEMs = res.data.keys.reduce(
(pems, jwk) => ({ ...pems, [jwk.kid]: jwkToPem(jwk) }),
[],
);
fs.writeFile(
`${__dirname}/${relativeOutPath}`,
`module.exports = ${JSON.stringify(PEMs, null, 2)}`,
err => console.log(
err || `wrote PEM key:value pairs @\n${__dirname}/${relativeOutPath}`,
),
);
};
generatePEMs();
{
"name": "gen-aws-pems",
"version": "1.0.0",
"description": "generates an object of kid:RSA values for verifying AWS cognito tokens",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "the-vampiire",
"license": "MIT",
"dependencies": {
"axios": "^0.19.0",
"jwk-to-pem": "^2.0.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment