I’m building a React frontend that needs to validate the JWT received from the Genesys Cloud implicit grant flow. The goal is to keep the trace context alive across the UI components and subsequent API calls, so I want to verify the token’s integrity client-side before making requests.
The issue is that the Genesys Cloud ID token uses RS256, and I’m struggling to fetch the public keys from the JWKS endpoint reliably in the browser. CORS headers on https://api.mypurecloud.com/oauth/jwks are blocking the direct fetch from the React app running on localhost.
Here’s the validation logic I’m using with jose:
import { jwtVerify, importJWK, createRemoteJWKSet } from 'jose';
const JWK_SET = createRemoteJWKSet(new URL('https://api.mypurecloud.com/oauth/jwks'));
export async function validateToken(token) {
try {
const { payload, protectedHeader } = await jwtVerify(token, JWK_SET, {
issuer: 'https://api.mypurecloud.com',
audience: 'my-client-id',
});
return { valid: true, payload };
} catch (err) {
console.error('Token validation failed', err);
return { valid: false, error: err.message };
}
}
The browser throws a CORS error when trying to fetch the JWKS. I’ve tried using a CORS proxy, but that feels like a hack for production. Is there a recommended way to handle this? Should I be using a different validation library or approach for React apps?
I need this to work so I can inject the trace context into my OpenTelemetry spans. The token seems valid when I decode it manually, but the validation fails due to the key fetch issue. Any ideas on how to bypass the CORS block or validate the token differently?