Created
October 18, 2022 13:06
-
-
Save isholaomotayo/dc585172e3c45b337e598c92b8385848 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function verifyToken(authHeader: string): Promise<JwtPayload> { | |
const token = getToken(authHeader) | |
const jwt = decode(token, { complete: true }) as Jwt | |
logger.info(`jwt after decoding: ${jwt}`) | |
const keyId = jwt.header.kid | |
logger.info(`keyId: ${jwt}`) | |
const pemCertificate = await getCertificateByKeyId(keyId) | |
return verify(token, pemCertificate, { algorithms: ['RS256'] }) as JwtPayload | |
} | |
function getToken(authHeader: string): string { | |
if (!authHeader) throw new Error('No authentication header') | |
if (!authHeader.toLowerCase().startsWith('bearer ')) | |
throw new Error('Invalid authentication header') | |
const split = authHeader.split(' ') | |
const token = split[1] | |
return token | |
} | |
async function getCertificateByKeyId(keyId: string): Promise<string> { | |
if (cachedCertificate) return cachedCertificate | |
const response = await Axios.get(jwksURL) | |
const keys = response.data.keys | |
if (!keys || !keys.length) throw new Error('No JWKS keys found') | |
const signingKeys = keys.filter( | |
(key) => | |
key.use === 'sig' && | |
key.kty === 'RSA' && | |
key.alg === 'RS256' && | |
key.n && | |
key.e && | |
key.kid === keyId && | |
key.x5c && | |
key.x5c.length | |
) | |
if (!signingKeys.length) throw new Error('No JWKS signing keys found') | |
const matchedKey = signingKeys[0] | |
const publicCertificate = matchedKey.x5c[0] // public key | |
cachedCertificate = getPemFromCertificate(publicCertificate) | |
logger.info('pemCertificate:', cachedCertificate) | |
return cachedCertificate | |
} | |
function getPemFromCertificate(cert: string): string { | |
let pemCert = cert.match(/.{1,64}/g).join('\n') | |
return `-----BEGIN CERTIFICATE-----\n${pemCert}\n-----END CERTIFICATE-----\n` | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment