Authentication
Authentication in Hyper Fetch consists of two steps. We will introduce changes in the Builder instance and subsequent commands created from it.
First, we need to add code for request authentication
In the example below we are doing it by adding a token header to the currently sent command.
export const builder = new Builder({ url }).onAuth((command) => {
// Redux store or any other storage to get current value of token
const state = store.getState();
const authToken = state.auth.token;
// For every authenticated command we want to
// add the header with token and return the extended command
return command.setHeaders({
...command.headers,
Authorization: `Bearer ${authToken}`,
});
});
The second step is to put the auth: true
option in the command to make it available for onAuth
method of builder.
export const getUsers = builder.createCommand()({
endpoint: "/users",
auth: true,
});
That's it, from now on, each request made using this command will be authenticated with our token.
Refresh token
To refresh the token, we can add a special onError
interceptor to our
Builder. It intercepts errors received in our requests and it is asynchronous,
which allows for efficient handling of such cases.
To properly avoid the infinite refresh loop
of the token, we need to protect ourselves by setting the used
field
to true thanks to the appropriate method setUsed
. This will allow us to easily verify whether our commend has
already gone through the intercept process or not.
Example
export const builder = new Builder({ url }).onError(async (response, command) => {
const status = response[2];
const refreshToken = localStorage.getItem(REFRESH_TOKEN_STORAGE_FIELD);
// Check if command has the used value - this will ensure you to
// not go into infinite loop and trigger this operation only once
if (!command.used && refreshToken && status === 401) {
// Prepare the refresh token command
const postRefreshToken = builder.createCommand<LoginResponse, LoginData>()({
endpoint: "/refresh-token",
method: "POST",
});
// Call the command to receive new tokens
const [data] = await postRefreshToken.setData({ refreshToken }).exec();
if (data) {
// Safe the new tokens
localStorage.setItem(TOKEN_STORAGE_FIELD, data.token);
localStorage.setItem(REFRESH_TOKEN_STORAGE_FIELD, data.refreshToken);
// Repeat the request and set it "used"
return command.setUsed(true).send();
}
}
// Return the initial response is something goes wrong
return response;
});