We are using a customer provided Keycloak instance which is running 16.1.1 and using the corresponding version of the Keycloak JS adapter in our SPA. Before going any further into this post, we have actively reviewed a number of topics on the matter, including this guide which we believe was created by a member of the active staff/community. One of the notions in this post is to not use localhost
, which frankly is not practical for local development. Further, as discussed below, we find that its also not the (at least apparent) cause of the issue).
Here is the context of the problem:
- Keycloak 16.1.1 running on remote resource
- Local SPA development running on
localhost
- Calls to
/token
for updating the access token will occassionally encounter a CORS error - Multiple calls may succeed prior to encountering the CORS error
- Originally a
setTimeout
call was done to refresh the token 15 seconds before it expired - Typically around the 5/6th call the error was encountered
- Keycloak will fail to initialize anymore as calling
init()
will try/token
again and fail
To programmatically debug this, we tried “rolling back” the timeout, to see if we could ever get a sequence to succeed. Access tokens are set to expire at 5 minutes (300 seconds) and refresh tokens at 30 minutes (1800 seconds). So the intervals were done in 1 minute rollbacks until we reached 1 minute, then they dropped to 5 second rollbacks:
- 4 minutes (fails)
- 3 minutes (fails)
- 2 minutes (fails)
- 1 minute (fails)
- 55 seconds (passes)
- 50 seconds (passes)
- …
- 5 seconds (passes)
At this point, each of the above test were run where the app was launched locally and let to run for 6-8 hours, and the tests that refreshed the token in an interval of < 1 minute always stayed alive, whereas anything > 1 minute would eventually encounter the CORS error. The < 1 minute test was extremely bound when testing at 1 second and 59 seconds, and was left for 24 hours in both of those cases, without encountering any issue reaching out to /token
. As mentioned at the beginning of this, the notion that localhost
is the problem, is not apparent as these tests were running on localhost
and seem to be related to token/session timeframes.
Lastly, we attempted to update the token using onTokenExpiration
but received mixed results, as this would sometimes go without issue for 6-8 hours and other times fail within 30 minutes. It should be noted that in all of these cases, updateToken(-1)
is being used to force an update regardless of the lifetime of the access token.
Due to security constraints, I cannot share the Client configuration (I can respond to inquiries if necessary), but here are the settings most relevant:
- Valid Redirect URLs:
http://localhost:3000/*
- Web Origins:
http:localhost:3000
Here are the Token settings for this Client:
At this point, we are unsure why refreshing the token works within the < 1 minute timeframe, but any other timeframe causes it to fail. We believe the issue lies somewhere within the Client configuration, but are unsure where. We’ve also enabled logging, but we don’t see any logs that indicate why a request might’ve been denied (as the browser states the Response headers are missing Access-Control-Allow-Origin. We do not have access to the location where the Keycloak instance is hosted, just the admin panel of the Realm.
Unfortunately, as noted we are bound to use 16.1.1 as provided, so updating is not an option.