Use axios to refresh access token
You should not allow a user to access resources that are protected; use must be authenticated.
One of the most common authentication mechanism is using Json Web Tokens
.
Here is the flow,
- User logged int providing correct credentials
- Server authenticates and returns two tokens: access token, and refresh token
- Every time user makes a request, access token will be sent on the request header with header type
Authorization
followed byBearer
.i.eBearer {accessToken}
- Server parses this token, validates it and allows the access
However, there is downside. If server issues a permanent token it will expose vulnerability i.e. token theft, or mis-use by other means.
To overcome this issue, it uses refresh token.
So, server generates access token with expiry less than a hour, or whatever is required as per the need. And, it generates refresh token with longer expiry.
What if access token expires?
- User makes a api call, server sends
401
as access token is expired - User initiates a follow up api call to refresh token i.e. to get a new access token.
- If refresh token is expired, server sends again
401
and user must be logged out.
Now, how to automate these calls?
I will give an example to automate this with axios.
import axios from 'axios';
import LocalStorageService from './services/local-storage.service';
import refreshToken from './refresh-token';
const Client = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
});
// request interceptor to add token to request headers
Client.interceptors.request.use(
async (config) => {
const token = LocalStorageService.getAccessToken();
if (token) {
config.headers = {
authorization: token,
};
}
return config;
},
(error) => Promise.reject(error)
);
// response interceptor intercepting 401 responses, refreshing token and retrying the request
Client.interceptors.response.use(
(response) => response,
(error) => {
const { config } = error;
if (error.response?.status === 401 && !config._retry) {
config._retry = true;
refreshToken(LocalStorageService.getRefreshToken())
.then((res) => {
const { accessToken } = res.data.data;
LocalStorageService.setAccessToken(accessToken);
return axios(config);
})
.catch((err) => {
if (err.response.status === 401) {
LocalStorageService.setUser(null);
window.location.href = '/login';
}
return Promise.reject(err);
});
}
return Promise.reject(error);
}
);
export default Client;