Ability to set callback that return fresh API Key
Context : Following the issue #772, we can now check remaining validity of API Key.
Problem : In our application, we are generating very short term API Keys (5 minutes) to always be compliant with filters and visibility that are set in the Key (from our backend according to user access rights).
It could be very cool to add a callback while creating the searchclient which will be called when API Key is near expiration and which should return a fresh API Key.
Workaround :
Currently, we are wrapping the search methods from searchclient into some of our wrappers that do the check before every request.
If we detect that API Key is expired, we generate a new searchclient with the updated API Key and use it to execute the query.
However there is two bad concerns about this workaround :
- As searchclient instance change, the
InstantSearchnode seems to detect it and relaunch a new query (which is now duplicated). - As searchclient instance change, what happen to the currently built query cache ? Reset ?
Yours faithfully, LCDP
Before thinking further on if and how to implement this, I'd like to answer your questions:
- InstantSearch has to redo a search when the search client instance changes, because it could for example change from a search client that is a noop to one that actually searches Algolia. These use cases are fairly rare, but it's easier to assume the search needs to be redone
- The cache is indeed recreated when you create a new search client, unless you manually create the cache outside of the algoliasearch call and pass that same instance when you recreate the client
import algoliasearch from 'algoliasearch/lite';
import { createBrowserLocalStorageCache } from '@algolia/cache-browser-local-storage';
import { createFallbackableCache } from '@algolia/cache-common';
import { createInMemoryCache } from '@algolia/cache-in-memory';
const appId = '...';
const caches = {
responsesCache: createInMemoryCache(),
requestsCache: createInMemoryCache({ serializable: false }),
hostsCache: createFallbackableCache({
caches: [
createBrowserLocalStorageCache({
key: `${algoliasearch.version}-${appId}`,
}),
createInMemoryCache(),
],
}),
};
const client = algoliasearch(appId, '...', { ...caches });
Hi @Haroenv,
Nice, thanks for this answer which is really informative ! I think that we are going to create the cache outside the client which will be a good fix for the second point !
Yours faithfully, LCDP
Hi @Haroenv,
Is there any news about this feature request ? We are still overidding the algolia search client methods with custom async to verify our api key prior to request but it is very ugly and hard to understand/maintain.
It could be good if we can give to the search client a method to generate an api key. It will work in combination of getSecuredApiKeyRemainingValidity. Before each algolia call, if the result of api key remaning validity is below a given value (1 minute ?) then method to generate a new api key is called prior to request.
Yours faithfully, LCDP
Unfortunately I think that you wouldn't want to generate a secured API key frontend, as when you generate it, you need access to the api key with higher permission to be able to generate the secured API key from. If that's available frontend, you could just as well not use secured API keys, but just a regular API key.
In our context, we can generate a secured frontend API Key without javascript client accessing the "mother" API Key with higher permission.
Context : When a user login into our app, it get a JWT access token and JWT refresh token which have different lifespan (see Oauth mechanism with token renewal).
When user want to contact Algolia, it request a secured API Key to our backend, using his JWT Access Token. The new Algolia Secured API Key will inherit the "Mother" API Key, have some restrictions linked to the user and have the same lifespan as the user JWT access token.
As it have a limited lifespan, the Secured API Key need to be refreshed and we would like to execute this check on Algolia Query to avoid trigger useless API Key generation every X minutes even if user is not interacting with Algolia.
In this context, the "Mother" api key can not be accessed directly in frontend (which would be a security flaw). The Secured API Key is temporary and can be generated only by logged in users.
What we are doing at the moment : We override every async network request from Algolia Search Client (search, searchForFacetValues, ...) and call a validity check against the Algolia Secured API Key lifespan. If timing is below a given value (1 minute for example), a request is sent to our backend to generate a new Secured API Key and this new key is used in the initial method/request call.
This is hard to maintain as we can miss some methods doing network request to Algolia API and we can have new ones or renaming on library version update.