Skip to content

Instantly share code, notes, and snippets.

@loginov-rocks
Created January 22, 2024 04:05
Show Gist options
  • Save loginov-rocks/baeb3b604a010c09b35de70635d803d7 to your computer and use it in GitHub Desktop.
Save loginov-rocks/baeb3b604a010c09b35de70635d803d7 to your computer and use it in GitHub Desktop.
WebSocket API Gateway Cognito Authorizer
import jwkToPem from 'jwk-to-pem';
// Simple in-memory cache, optional. In this Lambda it will always have a single promise stored because Region and User
// Pool ID are taken from the environment variables and remain unchanged within the life cycle of the Lambda, but I
// still kept this flexible in case someone will copy the code. Subject for improvement.
const getPemEncodedPublicKeysPromisesCache = new Map();
const getPemEncodedPublicKeysImplementation = async (jwksUrl) => {
console.log('jwksUrl', jwksUrl);
const response = await fetch(jwksUrl);
if (!response.ok) {
throw new Error(`Unable to fetch JWKS using URL ${jwksUrl}!`);
}
const json = await response.json();
const pemEncodedPublicKeys = new Map();
json.keys.forEach(({ kid, kty, n, e }) => {
pemEncodedPublicKeys.set(kid, jwkToPem({ kty, e, n }));
});
return pemEncodedPublicKeys;
};
const getPemEncodedPublicKeys = (region, userPoolId) => {
const jwksUrl = `https://cognito-idp.${region}.amazonaws.com/${userPoolId}/.well-known/jwks.json`;
if (!getPemEncodedPublicKeysPromisesCache.has(jwksUrl)) {
// The implementation is executed and set as the map element immediately to decrease the chances of the race
// conditions' impact (the same function triggered in parallel, but not yet resolved). Subject for improvement.
getPemEncodedPublicKeysPromisesCache.set(jwksUrl, getPemEncodedPublicKeysImplementation(jwksUrl));
}
return getPemEncodedPublicKeysPromisesCache.get(jwksUrl);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment