React + redux + axios + thunk,等待拦截器。响应刷新令牌

时间:2019-03-16 12:03:16

标签: javascript reactjs redux axios redux-thunk

我使用了redux和redux-thunk,并使用axios interceptors response作为刷新令牌,我的代码是:

axios.interceptors.response.use(response => {
    return response;
}, error => {
    if (error.response && error.response.data.error === 'token_expired') {
        axios.get('/refresh')
            .then(response => {
                let newToken = response.data.newToken;
                dispatch(refreshToken(newToken))
                error.config.headers.Authorization = 'Bearer ' + newToken;
                console.log(error.config);
                return axios.request(error.config);
            });
    } else {
        return Promise.reject(error);
    }
});

我的代码可以工作并且刷新令牌,但是redux操作不会等待axios.interceptors.response并且在刷新令牌重新运行undefined之前

谁可以解决这个问题?

更新

我将代码更改为:

axios.interceptors.response.use(response => {
    return response;
}, error => {
    if (error.response && error.response.data.error === 'token_expired') {
        dispatch(getNewToken(newToken => {
            error.config.headers.Authorization = 'Bearer ' + newToken;
            return axios.request(error.config);
        }))
    } else {
        return Promise.reject(error);
    }
});

和getNewToken是:

export const getNewToken = (onSuccess) => {
    return dispatch => {
        axios.get('/refresh')
            .then(response => {
                let newToken = response.data.newToken;
                dispatch(refreshToken(newToken))
                onSuccess(newToken);
            });
    }
}

当我检查浏览器Web开发人员时,在网络中,这项工作并要求使用新令牌重复执行,但我的操作不会再次运行以呈现响应

我哪里错了?

Update2:

我的中间件:

const jwtTokenRefresh = ({ dispatch, getState }) => (next => (action) => {
    const timeStamp = Math.floor(Date.now() / 1000);
    const expiration = getState().auth.expiration;
    if (expiration && timeStamp > expiration) {

        axios.get('/refresh')
            .then(response => {
                let newToken = response.data.newToken;
                dispatch(refreshToken(newToken))
            })
            .then(() => {
                next(action);
            })
    }else {
        return next(action);
    }
});

并刷新令牌操作:

export const refreshToken = dispatch => {
    return dispatch => {
        axios.get('/refresh')
            .then(response => {
                console.log(response);
                let newToken = response.data.newToken;
                const rememberMe = localStorage.getItem('token') ? true : false;
                dispatch(authSuccess(newToken, rememberMe))
            });
    }
}

1 个答案:

答案 0 :(得分:1)

您可以将设置新令牌作为回调函数传递给refreshToken()动作,并在refreshToken返回成功结果时调用它:

dispatch(refreshToken((newToken) => {
    error.config.headers.Authorization = 'Bearer ' + newToken;
    console.log(error.config);
    return axios.request(error.config);
  })
)

refreshToken 操作类似于

refreshToken(onSuccess, onFailure) {
     axios.post('/refreshTokenUrl')
     .then(responseData => {
         const {token} = responseData;
         onSuccess(token);
     })
}