Running into a wall with the Authorization Code + PKCE flow for our new Node.js SPA. The redirect back from Genesys Cloud works fine, getting the code and state in the URL params. But when I hit /oauth2/token to exchange that code, I get a 400 Bad Request with error: "invalid_grant" and error_description: "Code verifier mismatch".
I’m generating the code_verifier and code_challenge client-side using crypto before the auth request, then storing the verifier in sessionStorage. On the callback, I pull it out and send it in the POST body. Here’s the fetch call:
const response = await fetch('https://api.mypurecloud.com/oauth2/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code: urlParams.get('code'),
redirect_uri: window.location.origin,
client_id: CLIENT_ID,
code_verifier: sessionStorage.getItem('code_verifier')
})
});
I’ve double-checked the challenge method is S256. The verifier looks identical in the logs before sending and in storage. Is there a timing issue where the verifier gets wiped or encoded weirdly? Or does the Genesys token endpoint expect the verifier to be sent in a different way than standard OAuth2 specs?