【问题标题】:React + redux + axios + thunk, wait for interceptors.response refresh tokenReact + redux + axios + thunk,等待interceptors.response 刷新token
【发布时间】:2019-08-07 08:32:11
【问题描述】:

我使用了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 开发人员时,在网络中这项工作并请求使用新令牌重复并工作,但我的操作不会再次运行以呈现响应

我哪里错了?

更新2:

我的中间件:

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))
            });
    }
}

【问题讨论】:

标签: javascript reactjs redux axios redux-thunk


【解决方案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);
     })
}

【讨论】:

  • 谢谢,我检查了它并编辑了我的问题,请再次检查。
  • 究竟是什么不适合这种方式?是否使用新令牌调用 onSuccess()?我会推荐你​​而不是 error.config.headers.Authorization = 'Bearer' + newToken; 使用 axios.defaults.headers.Authorization = newToken,所以 axios 会在所有请求中发送新令牌
  • 我有一个名为 fetchItems 的操作,当运行它时,如果令牌未过期,它可以工作,但如果令牌过期,我的新代码可以工作并刷新令牌,如果检查开发人员工具 fetshed 项目,但是fetchItems 不再运行以获取项目并渲染它
  • 要重试 redux 操作,您应该实现 jwtTokenRefresh 中间件并在您的商店中使用它(我在第一条评论中提供的链接)。我试过一次,它对我有用。这是我的代码的链接,也许它会帮助你pastebin.com/HGZWCpUc。注意 onSuccessRefresh() 函数。那是成功刷新后再次调用动作的地方。如果您决定使用它,请不要忘记将其作为中间件应用到您的商店。
  • 正如我在不同的资源中看到的,每个人也在从后端发送令牌及其过期时间。您可以将其作为 Unix 时间戳发送,并将用户本地时间转换为 Unix 时间戳并进行比较。我可能经验太少,但我不知道如何以另一种方式做到这一点。我已经告诉了你我知道的一切 =)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-02
  • 2023-03-23
  • 2019-03-02
  • 2017-04-03
  • 2017-06-15
  • 1970-01-01
相关资源
最近更新 更多