我找到了解决此问题的方法。我不确定这是否是最佳做法,并且可能会有一些改进。
我最初的想法仍然存在:JWT刷新位于中间件中。
thunk如果
thunk使用中间件,则必须先使用它。
...const createStoreWithMiddleware = applyMiddleware(jwt, thunk)(createStore);
然后,在中间件代码中,我们检查令牌是否在任何异步操作之前到期。如果过期,我们还将检查是否已经在刷新令牌-
为了能够进行此类检查,我们向该州添加了对新令牌的承诺。
import { refreshToken } from '../actions/auth';export function jwt({ dispatch, getState }) { return (next) => (action) => { // only worry about expiring token for async actions if (typeof action === 'function') { if (getState().auth && getState().auth.token) { // depre jwt so that we know if and when it expires var tokenExpiration = jwtDepre(getState().auth.token).<your field for expiration>; if (tokenExpiration && (moment(tokenExpiration) - moment(Date.now()) < 5000)) { // make sure we are not already refreshing the token if (!getState().auth.freshTokenPromise) { return refreshToken(dispatch).then(() => next(action)); } else { return getState().auth.freshTokenPromise.then(() => next(action)); } } } } return next(action); };}最重要的部分是
refreshToken功能。该功能需要在刷新令牌时分派操作,以便状态将包含对新令牌的承诺。这样,如果我们调度同时使用令牌认证的多个异步操作,则令牌仅刷新一次。
export function refreshToken(dispatch) { var freshTokenPromise = fetchJWTToken() .then(t => { dispatch({ type: DONE_REFRESHING_TOKEN }); dispatch(saveAppToken(t.token)); return t.token ? Promise.resolve(t.token) : Promise.reject({ message: 'could not refresh token' }); }) .catch(e => { console.log('error refreshing token', e); dispatch({ type: DONE_REFRESHING_TOKEN }); return Promise.reject(e); }); dispatch({ type: REFRESHING_TOKEN, // we want to keep track of token promise in the state so that we don't try to refresh // the token again while refreshing is in process freshTokenPromise }); return freshTokenPromise;}我意识到这很复杂。我也担心调度
refreshToken动作本身不是动作。请让我知道您知道的其他使用Redux处理过期JWT令牌的方法。



