apache/flagon-useralejs

Add auth header callback option for UserALE

EandrewJones opened this issue · 0 comments

Problem

The current method of adding an authentication header to UserALE is static. The user sets the value as a string once when first configuring userale options, e.g.

userale.options({
    ...
    authHeader: `Bearer ${token}`, // <---- update token here
});

These are then sent as part of the POST requests to whichever back-end persistence endpoint was set. The problem is most authentication systems have a TTL on tokens and they may expire as frequently as every 30 mins or sooner. Therefore, the POST requests will fail because the token has expired.

Many auth systems will automatically refresh the token in the client's browser. We need an agnostic and dynamic way to update userALE's authHeader without forcing the user to reset the options every time there's an expiration.

Solution

We can allow users to register an authHeader callback function which fetches the current token and returns it as a properly formatted string (depending on which authentication method they're using on their back-end). This function would then be used in a pre-send hook, where we first fetch a non-expired token and then update the current authHeader field with it.

By following a strategy pattern, all we need to do is "enforce" the desired interface the callback function should follow. Then users can include whatever business logic is needed to achieve the token fetching. Of course, it's a bit tough to strictly enforce a function interface without Typescript, but we can document the pattern.

For end users, it would be as simple as:

const authCallback = (): string => {
  // Business logic here
  return `Bearer ${token}`
}

userale.registerAuthCallback(authCallback)

Pros

This is a simple and clean pattern for handling the token refresh lifecycle (or other challenges) without making any assumptions about which auth approaches end users are using. All we're assuming here is:

  1. they are utilizing the authHeader in some way; and
  2. it needs to be dynamically updated.

Cons

If the authCallback is async because it needs to make a network request, as opposed to say fetching a token directly from the browser, this would add some over-head to the rate at which we POST logs. However, it's better than an alternative where the headers go stale, POST requests 401, and users lose data.