我们的React Native Redux应用程序使用JWT令牌进行身份验证 . 有许多动作需要这样的令牌,并且许多动作同时被派遣,例如当app加载时
例如 .
componentDidMount() {
dispath(loadProfile());
dispatch(loadAssets());
...
}
loadProfile
和 loadAssets
都需要JWT . 我们将令牌保存在状态和 AsyncStorage
中 . 我的问题是如何处理令牌过期 .
最初我打算使用中间件来处理令牌到期
// jwt-middleware.js
export function refreshJWTToken({ dispatch, getState }) {
return (next) => (action) => {
if (isExpired(getState().auth.token)) {
return dispatch(refreshToken())
.then(() => next(action))
.catch(e => console.log('error refreshing token', e));
}
return next(action);
};
}
我遇到的问题是,对于 loadProfile
和 loadAssets
动作都会刷新令牌,因为在它们发送时令牌将过期 . 理想情况下,我想要在刷新令牌之前需要身份验证的"pause"操作 . 有没有办法用中间件做到这一点?
3 回答
我找到了解决这个问题的方法 . 我不确定这是否是最佳实践方法,并且可能会对其进行一些改进 .
我最初的想法仍然存在:JWT刷新是在中间件中 . 如果使用
thunk
,那么中间件必须在thunk
之前 .然后在中间件代码中,我们检查令牌是否在任何异步操作之前过期 . 如果它已过期,我们还会检查我们是否已经刷新了令牌 - 为了能够进行此类检查,我们会向状态添加新令牌的承诺 .
最重要的部分是
refreshToken
功能 . 该函数需要在刷新令牌时调度操作,以便状态将包含新令牌的承诺 . 这样,如果我们同时发送多个使用令牌身份验证的异步操作,则令牌只会刷新一次 .我意识到这很复杂 . 我也有点担心在
refreshToken
中调度行动本身并不是行动 . 请告诉我您知道的任何其他方法来处理使用redux到期的JWT令牌 .您可以改为使用商店变量来知道您是否仍在获取令牌,而不是“等待”某个操作完成:
样品减速机
现在是动作创建者:
安装组件时会调用此方法 . 如果auth键是陈旧的,它将调度一个动作将
fetching
设置为true并刷新令牌 . 请注意,我们还不会加载配置文件或资产 .新组件:
请注意,现在您尝试在挂载时加载您的东西,但在接收道具时也会在某些条件下加载(这将在商店更改时调用,因此我们可以保留
fetching
)当初始提取失败时,它将触发refreshToken
. 完成后,它将在商店中设置新令牌,更新组件,从而调用componentWillReceiveProps
. 如果它仍然没有取出(不确定这个检查是否必要),它将加载东西 .我围绕
redux-api-middleware
创建了一个简单的包装器来推迟操作并刷新访问令牌 .middleware.js
我在状态中保留令牌,并使用简单的帮助程序将Acess令牌注入请求标头
所以
redux-api-middleware
动作几乎保持不变我编写了article并共享了project example,它显示了JWT刷新令牌工作流程