Skip to content

Commit 67f2fab

Browse files
authored
[VUFIND-1755] Allow FOLIO token sharing between sessions. (vufind-org#4244)
1 parent dd3f8c6 commit 67f2fab

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

config/vufind/Folio.ini

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ debug_get_requests = false
2424
; more secure /auth/login-with-expiry method introduced in the Poppy release.
2525
legacy_authentication = true
2626

27+
; If set to true (the default), the driver will cache API tokens so that all end
28+
; users share the same active token, to reduce the number of tokens generated in
29+
; FOLIO's database. If set to false, each user session will generate its own
30+
; distinct token. Note that this setting will be automatically disabled if the
31+
; use_user_token setting below is set to true, as the options are incompatible.
32+
global_token_cache = true
33+
2734
[IDs]
2835
; Which FOLIO ID is VuFind using as its internal bibliographic ID?
2936
; Options:

module/VuFind/src/VuFind/ILS/Driver/Folio.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,19 @@ protected function checkTenantTokenExpired()
351351
|| strtotime('now') >= strtotime($this->tokenExpiration);
352352
}
353353

354+
/**
355+
* Should we use a global cache for FOLIO API tokens?
356+
*
357+
* @return bool
358+
*/
359+
protected function useGlobalTokenCache(): bool
360+
{
361+
// If we're configured to store user-specific tokens, we can't use the global
362+
// token cache.
363+
$useUserToken = $this->config['User']['use_user_token'] ?? false;
364+
return !$useUserToken && ($this->config['API']['global_token_cache'] ?? true);
365+
}
366+
354367
/**
355368
* Initialize the driver.
356369
*
@@ -362,11 +375,19 @@ public function init()
362375
{
363376
$factory = $this->sessionFactory;
364377
$this->sessionCache = $factory($this->tenant);
378+
$cacheType = 'session';
379+
if ($this->useGlobalTokenCache()) {
380+
$globalTokenData = (array)($this->getCachedData('token') ?? []);
381+
if (count($globalTokenData) === 2) {
382+
$cacheType = 'global';
383+
[$this->sessionCache->folio_token, $this->sessionCache->folio_token_expiration] = $globalTokenData;
384+
}
385+
}
365386
if ($this->sessionCache->folio_token ?? false) {
366387
$this->token = $this->sessionCache->folio_token;
367388
$this->tokenExpiration = $this->sessionCache->folio_token_expiration ?? null;
368389
$this->debug(
369-
'Token taken from cache: ' . substr($this->token, 0, 30) . '...'
390+
'Token taken from ' . $cacheType . ' cache: ' . substr($this->token, 0, 30) . '...'
370391
);
371392
}
372393
if ($this->token == null) {
@@ -1205,13 +1226,19 @@ protected function setTokenValuesFromResponse(Response $response)
12051226
if ($this->useLegacyAuthentication()) {
12061227
$this->token = $response->getHeaders()->get('X-Okapi-Token')->getFieldValue();
12071228
$this->tokenExpiration = gmdate('D, d-M-Y H:i:s T', strtotime('now'));
1229+
$tokenCacheLifetime = 600; // cache old-fashioned tokens for 10 minutes
12081230
} elseif ($cookie = $this->getCookieByName($response, 'folioAccessToken')) {
12091231
$this->token = $cookie->getValue();
12101232
$this->tokenExpiration = $cookie->getExpires();
1233+
// cache RTR tokens using their known lifetime:
1234+
$tokenCacheLifetime = strtotime($this->tokenExpiration) - strtotime('now');
12111235
}
12121236
if ($this->token != null && $this->tokenExpiration != null) {
12131237
$this->sessionCache->folio_token = $this->token;
12141238
$this->sessionCache->folio_token_expiration = $this->tokenExpiration;
1239+
if ($this->useGlobalTokenCache()) {
1240+
$this->putCachedData('token', [$this->token, $this->tokenExpiration], $tokenCacheLifetime);
1241+
}
12151242
} else {
12161243
throw new \Exception('Could not find token data in response');
12171244
}

0 commit comments

Comments
 (0)