如何解决如何为自定义 redux 中间件创建静默刷新操作创建器?
我正在为我的应用程序实现静默刷新,基本上用来自 httpOnly、安全、sameSite cookie 的新访问令牌替换现有的过期访问令牌。流程如下所示:
Silent refresh process diagram
在用 axios 拦截器撞墙之后,我决定一些自定义的 redux 中间件更适合我的目的。我已经让一切都按预期工作了(经过多次初始式的反复试验),但感觉如此笨拙且效率低下。这是我的中间件文件:
// Redux middleware
import users from "../api/auth/users";
import {
USER_REFRESH_FAIL,USER_REFRESH_REQUEST,USER_REFRESH_SUCCESS,} from "../constants/userConstants";
const requestMiddleware = ({ dispatch,getState }) => (next) => async (
action
) => {
const { userLogin } = getState();
if (!userLogin.userInfo || typeof action !== "function") return next(action);
const { accessTokenExpiry } = userLogin.userInfo;
const accessTokenExpiryTime = new Date(accessTokenExpiry).getTime();
if (Date.now() >= accessTokenExpiryTime) {
if (userLogin.refreshing) {
return next(action);
} else {
dispatch({
type: USER_REFRESH_REQUEST,});
await users
.post(
"/refresh",{ existingAccessToken: userLogin.userInfo.accessToken },{
headers: {
"Content-Type": "application/json",},}
)
.then(({ data }) => {
dispatch({
type: USER_REFRESH_SUCCESS,payload: data,});
})
.catch((error) => {
dispatch({
type: USER_REFRESH_FAIL,payload:
error.response && error.response.data.error.message
? error.response.data.error.message
: error.message,});
});
return next(action);
}
} else {
return next(action);
}
};
export default requestMiddleware;
我的后端“/refresh”路由简单地确认刷新凭据(来自 cookie),然后用新的替换过期的访问令牌,并将其与过期时间一起发回。我真的很想移动这个动作以与我的其他动作创建者一起生活,这样我就可以轻松地在我的应用程序的其他部分使用它。如果用户的信息未定义但 cookie 仍然存在(刷新页面或关闭会话),则特别作为应用程序范围的 useEffect。我试过在我的用户操作文件中像这样定义它:
// User action creators
export const refresh = () => async (dispatch,getState) => {
try {
dispatch({
type: USER_REFRESH_REQUEST,});
const { userLogin } = getState();
const config = {
headers: {
"Content-Type": "application/json",};
const { data } = await users.post(
"/refresh",config
);
await dispatch({
type: USER_REFRESH_SUCCESS,});
} catch (error) {
dispatch({
type: USER_REFRESH_FAIL,payload:
error.response && error.response.data.error.message
? error.response.data.error.message
: error.message,});
}
};
然后将我的中间件重新格式化为如下所示:
// Redux middleware
import {refresh} from "../actions/userActions";
const requestMiddleware = ({ dispatch,getState }) => (next) => async (
action
) => {
const { userLogin } = getState();
if (!userLogin.userInfo || typeof action !== "function") return next(action);
const { accessTokenExpiry } = userLogin.userInfo;
const accessTokenExpiryTime = new Date(accessTokenExpiry).getTime();
if (Date.now() >= accessTokenExpiryTime) {
if (userLogin.refreshing) {
return next(action);
} else {
await dispatch(refresh())
return next(action);
}
} else {
return next(action);
}
};
export default requestMiddleware;
但是当我测试它时,我收到了最大调用堆栈大小超出错误。我的直觉告诉我,这肯定与我在中间件中分派导入操作的方式有关,而且我在异步流程中犯了大错。我觉得这很简单,但我正在绕圈子追逐自己的尾巴,无法弄清楚。非常感谢您对此的任何帮助!
谢谢! 塞斯
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。