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 {