Authentication
Authentication in Hyper Fetch consists of two steps. We will introduce changes in the Client instance and subsequent requests 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 request.
export const client = new Client({ url }).onAuth((request) => {
// Redux store or any other storage to get current value of token
const state = store.getState();
const authToken = state.auth.token;
// For every authenticated request we want to
// add the header with token and return the extended request
return request.setHeaders({
...request.headers,
Authorization: `Bearer ${authToken}`,
});
});
The second step is to put the auth: true
option in the request to make it available for onAuth
method of client.
export const getUsers = client.createRequest()({
endpoint: "/users",
auth: true,
});
That's it, from now on, each request made using this request will be authenticated with our token.
Refresh token
To refresh the token, we can add a special onError
interceptor to our Client.
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 client = new Client({ url }).onError(async (response, request) => {
const status = response[2];
const refreshToken = localStorage.getItem(REFRESH_TOKEN_STORAGE_FIELD);
// Check if request has the used value - this will ensure you to
// not go into infinite loop and trigger this operation only once
if (!request.used && refreshToken && status === 401) {
// Prepare the refresh token request
const postRefreshToken = client.createRequest<LoginResponse, LoginData>()({
endpoint: "/refresh-token",
method: "POST",
});
// Call the request 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 request.setUsed(true).send();
}
}
// Return the initial response is something goes wrong
return response;
});