在 Axios 响应拦截器中反应显示弹出窗口
React Showing popup in Axios response Interceptors
我正在 React 中使用刷新令牌和 JWT 令牌身份验证。我的用例是,
如果 JWT 令牌已过期,请调用刷新令牌并再次使用 API。但是,如果刷新令牌也已过期,我想向用户显示一个警报弹出窗口(会话已过期。重新登录),然后转到登录页面。这是我的代码。我能够路由到登录页面,但我不知道如何在路由之前触发警报弹出窗口。
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;
removeLocalStorageData
存储功能将从本地存储中清除所有令牌和数据。我不想显示 window.alert 函数来显示弹出窗口。在路由到登录页面之前,还有其他方法可以显示弹出窗口吗?
我想弹出组件。我无法在拦截器中发送状态。我正在使用任何 redux。使用我自己的自定义上下文提供程序。
为了替代window.alert
,您可以使用像sweet alert2 or react-toastify这样的通知组件,它可以在反应组件之外调用。
对于 react-toastify
,您需要在应用程序的根级别添加 <ToastContainer />
组件。
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;
我正在 React 中使用刷新令牌和 JWT 令牌身份验证。我的用例是, 如果 JWT 令牌已过期,请调用刷新令牌并再次使用 API。但是,如果刷新令牌也已过期,我想向用户显示一个警报弹出窗口(会话已过期。重新登录),然后转到登录页面。这是我的代码。我能够路由到登录页面,但我不知道如何在路由之前触发警报弹出窗口。
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;
removeLocalStorageData
存储功能将从本地存储中清除所有令牌和数据。我不想显示 window.alert 函数来显示弹出窗口。在路由到登录页面之前,还有其他方法可以显示弹出窗口吗?
我想弹出组件。我无法在拦截器中发送状态。我正在使用任何 redux。使用我自己的自定义上下文提供程序。
为了替代window.alert
,您可以使用像sweet alert2 or react-toastify这样的通知组件,它可以在反应组件之外调用。
对于 react-toastify
,您需要在应用程序的根级别添加 <ToastContainer />
组件。
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;