Skip to content

Instantly share code, notes, and snippets.

@jiyuhan
Created December 27, 2021 19:34
Show Gist options
  • Save jiyuhan/c30fd92311cac7008b5188c8c53db7cf to your computer and use it in GitHub Desktop.
Save jiyuhan/c30fd92311cac7008b5188c8c53db7cf to your computer and use it in GitHub Desktop.
Caching JWKS
import * as https from 'https';
import { JwksModel, JwksKidToPemMap } from '../models/jwks';
import jwkToPem from 'jwk-to-pem';
import { AWS_CONFIG } from '../variables-config';
export class CachedJwks {
private static jwks: JwksKidToPemMap = new Map<string, string>();
private static invalidTime = 0;
static get(): Promise<JwksKidToPemMap> {
// env vars are loaded here because of line length restriction
const { AWS_COGNITO_IDP_ENDPOINT, AWS_COGNITO_USER_POOL_ID } = AWS_CONFIG;
return new Promise((resolve, reject) => {
if (Date.now() < CachedJwks.invalidTime && CachedJwks.jwks) return resolve(CachedJwks.jwks);
https
.get(
`${AWS_COGNITO_IDP_ENDPOINT}/${AWS_COGNITO_USER_POOL_ID}/.well-known/jwks.json`,
(res) => {
let data = '';
res.on('data', (d) => {
data += d;
});
res.on('end', () => {
// cheating: we know for fact that
// this well-known endpoint allows caching
// for 1 day. It is supposed to be 86400, but
// API call takes time, giving 50 seconds to
// be safe
CachedJwks.invalidTime = Date.now() + 86350 * 1000;
const newJwks = JSON.parse(data) as JwksModel;
const kidToPemMap = newJwks.keys.reduce((prevMap, currentJwk) => {
return prevMap.set(currentJwk.kid, jwkToPem(currentJwk));
}, new Map<string, string>());
CachedJwks.jwks = kidToPemMap;
resolve(kidToPemMap);
});
}
)
.on('error', (e) => {
reject(e);
});
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment