We’ve got a React frontend handling the implicit grant flow for Genesys Cloud auth. The SDK handles the redirect and gives me back the id_token as a JWT. I need to verify this token server-side before letting the user into the main app, but I’m hitting a wall with the signature verification.
The token decodes fine in jwt.io, and the iss claim matches https://api.mypurecloud.com. I’m trying to use the JWKS endpoint https://api.mypurecloud.com/.well-known/jwks.json to grab the public key.
Here’s the gist of the validation logic in our Node middleware:
const jwksClient = require('jwks-rsa');
const jwt = require('jsonwebtoken');
const client = jwksClient({
jwksUri: 'https://api.mypurecloud.com/.well-known/jwks.json'
});
function getKey(header, callback) {
client.getSigningKey(header.kid, (err, key) => {
const signingKey = key.publicKey || key.rsaPublicKey;
callback(null, signingKey);
});
}
app.use((req, res, next) => {
const token = req.headers.authorization.split(' ')[1];
jwt.verify(token, getKey, { algorithms: ['RS256'] }, (err, decoded) => {
if (err) {
return res.status(401).json({ error: 'Invalid token' });
}
req.user = decoded;
next();
});
});
The issue is that jwt.verify always throws JsonWebTokenError: invalid signature. The kid in the header matches one of the keys in the JWKS response. I’ve double-checked the aud and iss claims manually, and they look correct.
Am I missing a step in the key extraction? Or is the implicit grant token signed differently than the standard OAuth2 tokens? The docs mention using the api.mypurecloud.com domain, but maybe the SDK uses a different signing key set for the web widget flow.
Running jsonwebtoken v9.0.0. Any idea why the signature check is failing?