Closed hazcod closed 2 years ago
Great idea. It's out of scope for the @cfworker/jwt
lib but you could implement it in your project by taking control of the jwks fetching:
import { getJwks, importKey } from '@cfworker/jwt';
const iss = 'https://example.auth0.com';
const kvKey = 'jwks:' + iss;
let jwks = await NAMESPACE.get(kvKey, { type: 'json' });
if (!jwks) {
jwks = await getJwks(iss);
await NAMESPACE.put(JSON.stringify(jwks));
}
await Promise.all(jwks.keys.map(jwk => importKey(iss, jwk)));
@jdanyow Thank you! This works:
import { getJwks, importKey, parseJwt } from '@cfworker/jwt';
export async function getVerifyToken(event)
{
let jwt = event.request.headers.get('Authorization');
if (! jwt) { return null; }
jwt = jwt.replace('Bearer ', '');
const issuer = 'https://' + AUTH0_DOMAIN + '/';
const audience = AUTH0_CLIENTID;
const kvKey = 'jwks:' + issuer;
let jwks = await JWKS.get(kvKey, { type: 'json' });
if (!jwks) {
console.log('retrieving new JWKS: ' + issuer);
jwks = await getJwks(issuer);
await JWKS.put(kvKey, JSON.stringify(jwks), {expirationTtl: 60 * 60});
}
else {
console.log('using cached JWKS: ' + issuer);
}
await Promise.all(jwks.keys.map(jwk => importKey(issuer, jwk)));
const result = await parseJwt(jwt, issuer, audience);
if (! result.valid) {
console.log('invalid token: ' + result.reason);
return null;
}
return result.payload;
}
Would be nice to store the JWKS with a TTL of 1 hour in Cloudflare KV.