I am working with Refresh token and JWT token authentication in React. My use case is, If the JWT token is expired, Call Refresh token and consume the API again. But if the Refresh token also expired, I want to show one alert popup to the user(Session is expired. Log in again), and route to the sign-in page. Here is my code. I am able to route to the Sign in Page but I don't know how to trigger an alert popup prior to the routing.
API.interceptors.request.use(
(config) => {
config.headers["Authorization"] = getToken() || "";
return config;
},
(error) => {
return Promise.reject(error);
}
);
const refreshTokenAPI = async () => {
return await API.post("/refresh-token", {
token: getRefreshToken("refresh_token"),
});
};
export const doRefreshToken = async (err, API) => {
// const history = useHistory()
const originalConfig = err.config;
if (err.response) {
// Access Token was expired
if (err.response.status === 401 && !originalConfig._retry) {
originalConfig._retry = true;
try {
const rs = await refreshTokenAPI();
const { token, refreshToken } = rs.data;
setToken(token);
setRefreshToken(refreshToken);
return API(originalConfig);
} catch (_error) {
removeLocalStorageData(); // Removes all the token from local storage. If token is not in Local storage, the route will redirect to Sign in Page
window.location.reload()
return Promise.reject(_error);
}
}
if (err.response.status === 403 && err.response.data && originalConfig.url === '/refresh-token') {
removeLocalStorageData(); // Removes all the token from local storage. If token is not in Local storage, the route will redirect to Sign in Page
window.location.reload()
}
if (err.response.status === 403 && err.response.data) {
return Promise.reject(err.response.data);
}
}
}
API.interceptors.response.use(
(res) => {
return res;
},
async (err) => {
if (err.response.status == 401 || err.response.status == 403) {
return await doRefreshToken(err, API);
} else {
return Promise.reject(err);
}
}
);
export default API;
The removeLocalStorageData
storage function will clear all the tokens and data from the Local storage. I don't want to show window.alert function to show the popup. Is there any other way to show the popup before routing to the Sign-in page?
I want to popup the component. I am not able to dispatch a state in the interceptors. I am using any redux. Using my own custom context providers.
For alternative to window.alert
you can use notification component like sweet alert2 or react-toastify, which can be called outside react component.
For react-toastify
, you need to add <ToastContainer />
component, at the root level of your app.
import axios from "axios";
import Swal from "sweetalert2";
const api = axios.create({
baseURL: "https://reqres.in/api"
});
api.interceptors.response.use(
(res) => {
return res;
},
async (err) => {
if (err.response.status == 401 || err.response.status == 400) {
Swal.fire("Can you see me?");
}
return Promise.reject(err);
}
);
export default api;