From 068fd5c321872a6251e7fbd399dc83d2ccc7e620 Mon Sep 17 00:00:00 2001 From: Janek Beck Date: Thu, 24 Apr 2025 19:31:39 +0200 Subject: [PATCH] Set default timeSkew to 60 seconds to avoid forced token refresh (#52) Closes #52 Signed-off-by: Janek Beck --- lib/keycloak.d.ts | 10 ++++++---- lib/keycloak.js | 33 ++++++++++++--------------------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/lib/keycloak.d.ts b/lib/keycloak.d.ts index 9f5e07c..6960dac 100644 --- a/lib/keycloak.d.ts +++ b/lib/keycloak.d.ts @@ -139,8 +139,10 @@ export interface KeycloakInitOptions { idToken?: string; /** - * Set an initial value for skew between local time and Keycloak server in - * seconds (only together with `token` or `refreshToken`). + * Set an initial value for skew between local and Keycloak server time (in + * seconds). This is also used to determine whether the initial + * token is still valid (only together with `token` or `refreshToken`). + * @default 60 */ timeSkew?: number; @@ -472,8 +474,8 @@ declare class Keycloak { idTokenParsed?: KeycloakTokenParsed; /** - * The estimated time difference between the browser time and the Keycloak - * server in seconds. This value is just an estimation, but is accurate + * The estimated time difference between the browser and the Keycloak + * server time (in seconds). This value is just an estimation, but is accurate * enough when determining if a token is expired or not. */ timeSkew: number | null; diff --git a/lib/keycloak.js b/lib/keycloak.js index 5941b63..9734590 100755 --- a/lib/keycloak.js +++ b/lib/keycloak.js @@ -69,8 +69,8 @@ export default class Keycloak { responseType = 'code'; /** @type {KeycloakFlow} */ flow = 'standard'; - /** @type {number?} */ - timeSkew = null; + /** @type {number} */ + timeSkew = 60; /** @type {string=} */ redirectUri; /** @type {string=} */ @@ -865,7 +865,7 @@ export default class Keycloak { } } else { try { - await this.updateToken(-1); + await this.updateToken(); this.onAuthSuccess?.(); } catch (error) { this.onAuthError?.(); @@ -1437,11 +1437,6 @@ export default class Keycloak { throw 'Not authenticated'; } - if (this.timeSkew == null) { - this.#logInfo('[KEYCLOAK] Unable to determine if token is expired as timeskew is not set'); - return true; - } - if (typeof this.tokenParsed.exp !== 'number') { return false; } @@ -1460,13 +1455,11 @@ export default class Keycloak { * @param {number} minValidity * @returns {Promise} */ - async updateToken(minValidity) { + async updateToken(minValidity = 5) { if (!this.refreshToken) { throw new Error('Unable to update token, no refresh token available.'); } - minValidity = minValidity || 5; - if (this.#loginIframe.enable) { await this.#checkLoginIframe(); } @@ -1574,17 +1567,15 @@ export default class Keycloak { this.timeSkew = Math.floor(timeLocal / 1000) - this.tokenParsed.iat; } - if (this.timeSkew !== null) { - this.#logInfo('[KEYCLOAK] Estimated time difference between browser and server is ' + this.timeSkew + ' seconds'); + this.#logInfo('[KEYCLOAK] Estimated time difference between browser and server is ' + this.timeSkew + ' seconds'); - if (this.onTokenExpired) { - var expiresIn = (this.tokenParsed.exp - (new Date().getTime() / 1000) + this.timeSkew) * 1000; - this.#logInfo('[KEYCLOAK] Token expires in ' + Math.round(expiresIn / 1000) + ' s'); - if (expiresIn <= 0) { - this.onTokenExpired(); - } else { - this.tokenTimeoutHandle = window.setTimeout(this.onTokenExpired, expiresIn); - } + if (this.onTokenExpired) { + var expiresIn = (this.tokenParsed.exp - (new Date().getTime() / 1000) + this.timeSkew) * 1000; + this.#logInfo('[KEYCLOAK] Token expires in ' + Math.round(expiresIn / 1000) + ' s'); + if (expiresIn <= 0) { + this.onTokenExpired(); + } else { + this.tokenTimeoutHandle = window.setTimeout(this.onTokenExpired, expiresIn); } } } else {