The @rhapsody/tokens package is now available and replaces both services/tokenService.js and the User Angular module. The service exposes the getToken function to asynchronously fetch a valid JWT token for the currently authenticated user and cache it for a variable amount of time. The service also exposes a cacheToken function to manually populate the cache with a JWT.
Why cache the token for a variable amount of time?
User JWTs issued from our system expire after 10 minutes. To avoid the thundering herd problem, we cache the token for a randomly distribute time between 5 and 9 minutes. Distributing out when tokens are refetched allows for more stable, less spike-y traffic to the endpoint issuing the tokens.
For example, consider a scenario where all user JWTs for all logged in users are invalidated at once (this has happened before). Every user currently in the application would need their JWT refetched from the token endpoint. This results in a huge spike in traffic to that endpoint, quite probably causing performance degradation as well. If we did not randomly distribute out the token refetching for subsequent tokens (i.e. if we waited the full 10 minutes for everyone), there would be constant huge spikes in traffic to the token endpoint every 10 minutes. Distributing out the refetches allows us to avoid the subsequent traffic spikes.
Example
import { getToken } from '@rhapsody/tokens'
async function makeAuthenticatedRequest() {
const { token } = await getToken()
const response = await fetch('/endpoint/requiring/token/auth', {
headers: {
Authentication: `Bearer ${token}`,
},
})
return response.status
}
The tokens service is written in Typescript and can be used in JavaScript and Typescript code. New code should use this service and any existing non-Angular code should be refactored to use this service as well. Existing Angular code referencing the User module can be left as-is since the User module now uses the tokens service under the hood.