axios-token-manager
v1.0.1
Published
A manager for Auth Tokens using Axios in a Node API Server or a JS Client
Downloads
450
Maintainers
Readme
axios-token-manager
A library to manage caching of Axios Tokens with automatic refresh of Token on expiry or on error due to early revocation of the Token by the backend system. It can be used on a Node API Server as well as on a front end application.
Table of Contents
Purpose
The purpose of Axios-Token-Manager is to cache an Authentication Token during its validity period. This reduces the number of calls that need to be made on the back end to fetch authentication tokens, and improves response speeds and reduces latency.
The Axios-Token-Manager needs to be provided with a function which when invoked returns a new Authentication Token. Along with an access_token
field, the token response should include an expires_in
field giving the number of seconds till the token expires.
The Axios-Token-Manager is setup with an instance of Axios to which it applies request and response interceptors. All requests are intercepted and the Authentication Token is applied to the header of the outgoing request.
The Axios-Token-Manager will get a new Authentication Token a short time before the current token is due to expire, thereby ensuring that there is always a valid token available to be used. In the event that a request is being made and there is no valid token, then a fresh token will be requested and used in the Authentication header of the request, and then the fresh token will get cached.
Backend systems can sometimes revoke an Authentication Token before its expiry time. A request using such a token will fail with a 401 and possibly a 403 error. The Axios Token Manager intercepts all response and looks out for 401 errors. On receipt of a 401, it starts a recovery cycle in which it invalidates the cached token and fetches a new Token, which it caches. It then tries to recover the failed request by making a fresh request to the back end using the new Token. Only once this succeeds will the response be sent back to the caller. So the caller is unaware of what is happening and just gets a slightly delayed success response.
In case callers want to be kept aware of what is happening under the hood there are a number of callbacks that can be hooked into.
Features
- Fetch Authentication token using provided function
- Works out time till token expires
- Caches Authentication Token
- Applies Authentication Token to all outgoing requests on instance
- Fetches new Authentication Token a short time before current cached token expires
- Recovers from situation where the back end revokes a token before its expiry time is up
- Monitors response and in case of a 401, it fetches a new Authentication token and retries the request with fresh token
- After recovery from an early revokation of the Authentication token, it caches the fresh token
- Adds interceptors on the Request and Response of the provided Axios Instance
- Callbacks to notify calling application of token refresh, authentication fail, recovery try and recovery abort
- Format and configure authentication header
- Full Configuration of settings
Installing
Package manager
Using npm:
$ npm install axios-token-manager
Using yarn:
$ yarn add axios-token-manager
Once the package is installed, you can import the library using import
or require
approach:
import tokenManager from 'axios-token-manager';
If you use require
for importing:
const tokenManager = require('axios');
Usage
This defines a file which has a default export of an axios instance wired up with the axios-token-manager.
The axios-oauth-client library has been used here as an example for the implementation of the function to get a new Token, it can of course be replaced by your preferred oauth or token library, or your own implementation to get a token.
note: instance
and getCredentials
are the two required configuration settings, the other settings are all optional.
import axios from 'axios';
import oauth from 'axios-oauth-client';
import tokenManager, { TokenProvider, Settings } from 'axios-token-manager';
// Define an Axios instance using a common baseURL, timeout and the common headers for all requests
...
const instance = axios.create({
baseURL,
timeout,
headers
});
// define tokenURL to fetch the authorization token from, a clientId and a client secret
...
const getCredentials = oauth.clientCredentials(
axios.create(),
tokenURL,
clientId,
clientSecret
) as TokenProvider;
// define other optional settings for callbacks and other configurations (see API for config)
...
const settings: Settings = {
instance,
getCredentials,
... // define other optional configuration
};
tokenManager(settings);
export default instance;
Using all configurable options
The above example only used the two required settings. Below is an example using all the settings.
const settings: Settings = {
instance,
getCredentials,
refreshBuffer,
header,
formatter,
refreshOnStatus,
tokenTryThreshold,
maxRecoveryTries,
addTokenToLogs,
onTokenRefresh,
onAuthFail,
onTokenRequestFail,
onRecoveryTry,
onTokenTryThreshold,
onRecoveryAbort,
};
tokenManager(settings);
export default instance;
Token Shape
The Token has the interface shown below.
export interface Token {
access_token: string;
token_type?: string;
expires_in: number;
scope?: string;
}
access_token
andexpires_in
are mandatory keys.token_type
andscope
are currently not used.access_token
is sent across in the Authorization Header.expires_in
field is expected to be in seconds and is used to work out how long to cache the token.
API
instance
An Axios Instance. This instance should be used to make all requests that require an authentication header. The axios-token-manager will intercepts requests made by this instance and add an authentication header.
getCredentials
A function called by the axios-token-manager whenever it needs to get a fresh Token. It needs to implement the TokenProvider
type shown below. It is a mandatory setting.
export type TokenProvider = () => Promise<Token>;
refreshBuffer
The number of seconds at which the Token is refreshed before expiration of the currently cached token. Defaults to 10 seconds.
header
The Header which is added to outgoing requests. Default is Authorization
formatter
A function which takes in the access_token
and returns the value to be assigned to the Header. It has the following type definition.
export type Formatter = (accessToken: string) => string;
refreshOnStatus
Array of Http Status codes on return of which the Token Manager will attempt to recover by fetching a new Token and retrying the request with the new Token. The default is [401]
.
tokenTryThreshold
If a request for a Token fails, then a new attempt is made to get a Token. Once the number of attempts reaches the tokenTryThreshold
then a callback is invoked. The callback will be invoked again for every multiple of the tokenTryThreshold
. The default is 10, therefore on every 10th failed attempt to get a fresh token the onTokenTryThreshold
callback will be invoked.
maxRecoveryTries
The number of attempts to recover from a request which failed with an authentication error are counted. At each failure, a new token will be requested and a fresh attempt to recover made. The maxRecoveryTries
sets the limit after which the system will no longer try and recover and it will send an error response back to the original caller. The default value is 5.
addTokenToLogs
A boolean which controls whether the access_token
value is returned in callbacks. When the access_token
is returned it is part of a longer string giving the context. Default is false
.
onTokenRefresh
Callback function when the Token is refreshed. If addTokenToLogs
is true, a message containing the new Token's access_token
is sent as an argument.
onAuthFail
Callback function when the authentication fails and a status in the refreshOnStatus
array is returned. If addTokenToLogs
is true, a message containing the failed Token's access_token
is sent as an argument.
onTokenRequestFail
Callback function when a request for a new Token fails.
onRecoveryTry
Callback invoked when an a attempt is made to resend the request using a fresh token after the earlier one failed with an authentication error defined in the refreshOnStatus
setting. When addTokenToLogs
is true, the callback will get invoked with a message giving the new access_token
being used in the recovery attempt.
onTokenTryThreshold
Callback invoked when the number of failed attempts to get a new token reaches the tokenTryThreshold
or any of its multiples. The callback is called with the number of failed tries an a parameter.
onRecoveryAbort
Callback invoked when the number of attempts to recover from authentication failures reaches the maxRecoveryTries
.