Hi Miroslav,
What you are describing actually makes sense with how the PKCE flow and browser history handling behave differently in Firefox.
From what I have seen with the Genesys Cloud JavaScript SDK (purecloud-platform-client-v2), the SDK correctly attempts to remove the authorization code from the URL after the PKCE callback is processed, usually through history.replaceState().
The issue is that Angular routing/navigation in Firefox can reintroduce the original query string during route restoration/navigation timing, especially when using hash routing (#/services) together with query parameters.
So this is probably less a Genesys authentication issue and more:
Firefox + Angular router timing + hash-based routing interaction.
The important detail is:
the PKCE authorization code is single-use.
So once the page reloads with:
?code=xxxx
the SDK tries to exchange it again against:
/oauth/token
but the authorization code is already consumed/invalidated, which leads to the 400 response and the CORS-looking error symptom.
One thing that usually works better is explicitly cleaning the URL yourself immediately after successful authentication instead of relying only on the SDK cleanup behavior.
For example:
await client.loginPKCEGrant(clientId, redirectUri);
// Immediately remove the code parameter
window.history.replaceState(
{},
document.title,
window.location.pathname + window.location.hash
);
or alternatively:
const cleanUrl =
window.location.origin +
window.location.pathname +
window.location.hash;
window.history.replaceState({}, document.title, cleanUrl);
Another recommendation:
if possible, avoid mixing:
- hash routing (
#/route)
- OAuth query parameters
because Firefox tends to behave differently with URL reconstruction in those scenarios.
Using Angular PathLocationStrategy instead of HashLocationStrategy often avoids this entire class of problems.
Another thing worth validating:
make sure the PKCE callback handling runs only once during app bootstrap.
Some Angular applications accidentally trigger:
- auth initialization
- route guards
- app initializers
- session restoration
multiple times during refresh/navigation.
A defensive approach many teams use is:
if (window.location.search.includes('code=')) {
// Process PKCE callback once
}
and then persist authenticated state locally before Angular routing starts.
One important observation:
the CORS message itself is likely secondary.
The real issue is probably that Firefox is attempting to redeem an already-consumed authorization code, and the OAuth endpoint responds with an error that Firefox surfaces as a CORS-related failure.
So I would focus primarily on:
- aggressively removing
?code=
- avoiding hash routing if possible
- ensuring auth bootstrap executes once
- ensuring Angular navigation does not restore stale query params
rather than treating this as a pure CORS problem.
------------------------------
Gabriel Garcia
NA
------------------------------