Search code examples
javascripttypescripttokenkeycloak

Keycloak-js updateToken(minValidity) needs clarifications


I read many examples of the method in Keycloak-js without a clear explanation of the following method.

        updateToken(minValidity: number): KeycloakPromise<boolean, boolean>;

Note : I am using "keycloak-js": "^15.0.2"

Here is its documentation

    /**
     * If the token expires within `minValidity` seconds, the token is refreshed.
     * If the session status iframe is enabled, the session status is also
     * checked.
     * @returns A promise to set functions that can be invoked if the token is
     *          still valid, or if the token is no longer valid.
     * @example
     * ```js
     * keycloak.updateToken(5).then(function(refreshed) {
     *   if (refreshed) {
     *     alert('Token was successfully refreshed');
     *   } else {
     *     alert('Token is still valid');
     *   }
     * }).catch(function() {
     *   alert('Failed to refresh the token, or the session has expired');
     * });
     */

I am not a native english speaker. The term "expires within" is imprecise here.

An illustration is better understood. This method updateToken periodically checks if the token is expired or not during a window of time minValidity

enter image description here

When the token will be refreshed ?

When the keycloak token expiration is approaching, the token refreshment is either :

  • right prior its expiration date within the window of time minValidity ( blue)
  • OR after the next period update check. (orange)

In the blue case, it makes sense to have a large enough value of minValidity.

In the orange case, a small value is better.

I understand it is the blue case.

Bonus question : What will happen if the token duration < minValidity ?


Solution

  • Overall you want to avoid a situation where you send the AccessToken to a server/service and it gets rejected because it's not valid anymore.

    So it's a good idea to check validity everytime before using the token. As the documentation mentions: calls to a service/backend should only be made within the callback of the updateToken method. But beside that, there is no (automatic) periodic check for refreshing the token.

    The minValidity comes into place if you imagine a situation where the remaining AccessToken Lifetime is only 1 second. If you check the token on client side (isTokenExpired() => false) it will still be valid, but there is a probability, that when the request reaches a service, the token will not be valid anymore and gets rejected. => we want to avoid that

    The default value for minValidity is 5 seconds. So when calling the updateToken method and the token is still valid, but will expire within the next 5 seconds the token gets refreshed and any service/backend call inside the callback will use the new token. But a call itself does not necessarily mean a new token. If the remaining lifetime is long enough, nothing happens.

    So in your example the blue situation is correct. The second "update" call (if you mean a updateToken method call) will already trigger a token refresh. But again: The update calls are not done automatically. You need to either implement a periodic check or call updateToken before a backend call.

    To your bonus question: I looked into the code and in a fictional situation where e.g. minValidity is 60s but a new fresh token is always only valid for 30s, a call to updateToken will trigger a refresh everytime. But imho there will be no recurring "refresh-loop"