Disclaimer
This is not the best solution, is just a solution, there are probably better and more refined solutions on the web, but this one is simply a very simple one to implement.
Also here we are assuming you are using axios
to fetch data from the client.
What's the use case?
Let's say that you have your frontend application that consumes some APIs, and also your APIs requires some authentication token, like a JWT token, to be sent at every request, and you got this token after a login screen for example.
And JWT token they generally have an expiration date, it could be a hour, a day, or more (but you shouldn't use longer than that). Doesn't matter if here we are talking about a refresh token or the actual token, but at some point the API you are calling might refuse your requests because the token expired.
One way to solve this problem, is to handle it when you do the request in your code, so if you have an error on your request, you just redirect it back to the login screen.
Something like this perhaps:
import axios from 'axios';
const fetchData = async () => {
try {
const { data } = await axios.get('some/endpoint');
return data;
} catch (error) {
// this failed, so let's redirect to the login page
console.log(error);
window.location.href = '/';
}
}
And the above solution is ok, if you do only one request on your page it could work.
But, this also mean that if you have multiple pages, and maybe in every page you do multiple requests, this strategy becomes a bit cumbersome.
Use axios interceptors instead!
A better and simple way to handle the same problem, in a centrealized way, is to use axios interceptors instead.
With interceptors you can hook to a specific lifecycle of the API call, the request
and response
, and maybe modify the behaviours of them.
The axios.intercepotrs.request.use(config)
function has one argument, which is the configuration of the headers, while the axios.intercepotrs.response.use(response, error)
has two, which hooks with the .then
, or a successful response, and the .catch
, when we get an Error (any status that is not 2xx) as a response.
For example on the example below, we'll tell to axios to execute the code on every requests we do:
import axios from 'axios';
axios.interceptors.response.use(
response => response,
error => {
window.location.href = '/';
});
As you see above, we do nothing to the response, but if the error
is invoked, we redirect to our login page.
Note: you don't need to do this on every file, you just need to do it once, like on a configuration file for example.
If you want to have better control, like you want to target only some specific http status codes, let's say the 401 Unauthorized
, you can access to that via the error.response.status
, so our code will look like this:
axios.interceptors.response.use(
response => response,
error => {
if (error.response.status === 401) {
window.location.href = '/';
}
});
Do you want to handle this only for some requests?
Well, then you can also create an axios instance and use that instance only for some calls, for example:
// lib/customAxios.js
export const customAxios = axios.create({
baseURL: 'http://yourcoolapi.com/api',
headers: {
'X-Custom-Header': 'foobar'
}
});
customAxios.interceptors.response.use(
response => response,
error => {
if (error.response.status === 401) {
window.location.href = '/';
}
});
export default customAxios;
// yourcode.js
import customAxios from '/lib/customAxios.js';
const fetchData = async () => {
try {
const { data } = await customAxios.get('some/endpoint');
return data;
} catch (error) {
// this failed, so let's redirect to the login page
console.log(error);
}
}
Again, this is a very simple use case on how to use axios interceptors, there could be different strategies that works as well or better than this one.
Another one could be to use the request
interceptor, check the JWT token even before we actually call the API, and then request a new token, or redirect to the login, or else.
But the one I've explained in this post is probably the easiest to grasp and handle.
Top comments (5)
Hoy! Good article but you have a typo on every interceptors :)
Thanks for spotting it, I think I made up a new dinosaurs, the "intercepotors" :D
this is help, but need changes.
don't need to export const customAxios at top when you exported at bottom of file.
baseUrl changed to baseURL
If you look well, that meant to be in different files, to make it reusable ;-)
But you are right about
baseURL
Hi man! Thank you! This article was the only one that's really help me.