如何在Vuex Store中实现每隔9分钟自动调用Auth.currentSession()?
Vuex自动刷新AWS Amplify令牌的实现方案
问题描述
我正在开发一款频繁调用API的应用,有时请求会因令牌过期而失败。尝试过在发送请求前调用Auth.currentSession()并设置请求头,但因所用多数库不会等待该方法返回新令牌(当前令牌过期时),效果不佳。考虑最优方案是每隔9分钟手动调用Auth.currentSession()并将令牌存储到Vuex Store中,希望在Vuex的store.js中实现此自动执行逻辑,无需从其他组件触发。
原代码示例:
import { createStore } from 'vuex' import { Auth } from 'aws-amplify' export default createStore({ state: { session: null }, getters: { }, mutations: { setSession(state, value){ state.session = value } }, // This function will automatically refresh the token every 9 minutes. actions: { async refreshSession({ commit }){ try { const session = await Auth.currentSession() commit('setSession', session) } catch (error) { console.log(error) } } }, modules: { } })
解决方案
可以直接在Vuex Store初始化后启动定时任务,自动触发refreshSession动作,同时需处理定时器的清除逻辑避免内存泄漏。
修改后的Store代码
import { createStore } from 'vuex' import { Auth } from 'aws-amplify' export default createStore({ state: { session: null, refreshTimer: null // 存储定时器ID,用于后续清除 }, getters: { // 新增获取令牌的getter,方便外部调用 accessToken: state => state.session?.getIdToken().getJwtToken() }, mutations: { setSession(state, value){ state.session = value }, setRefreshTimer(state, timerId) { state.refreshTimer = timerId } }, actions: { async refreshSession({ commit }){ try { const session = await Auth.currentSession() commit('setSession', session) } catch (error) { console.error('刷新会话失败:', error) // 可在此添加令牌失效后的降级逻辑,例如跳转登录页 } }, startAutoRefresh({ dispatch, commit }) { // 首次加载立即刷新一次 dispatch('refreshSession') // 设置9分钟(540000毫秒)的定时任务 const timerId = setInterval(() => { dispatch('refreshSession') }, 9 * 60 * 1000) commit('setRefreshTimer', timerId) }, stopAutoRefresh({ state, commit }) { if (state.refreshTimer) { clearInterval(state.refreshTimer) commit('setRefreshTimer', null) } } }, modules: { } })
启动与停止定时任务
在应用入口(如main.js)中启动自动刷新,并在应用卸载时停止:
import { createApp } from 'vue' import App from './App.vue' import store from './store' const app = createApp(App) app.use(store) // 启动自动刷新 store.dispatch('startAutoRefresh') // 应用卸载时清除定时器 app.unmount = () => { store.dispatch('stopAutoRefresh') app._instance.unmount() } app.mount('#app')
或者在根组件的生命周期钩子中处理:
<!-- App.vue --> <script setup> import { onUnmounted } from 'vue' import { useStore } from 'vuex' const store = useStore() onUnmounted(() => { store.dispatch('stopAutoRefresh') }) </script>
注意事项
- 9分钟的间隔可根据实际令牌过期时间调整,建议比过期时间早1-2分钟,避免请求过程中令牌失效
- 需完善
refreshSession的错误处理逻辑,比如令牌彻底失效时跳转登录页 - 用户手动退出登录时,需调用
stopAutoRefresh停止定时任务,避免无效请求
内容的提问来源于stack exchange,提问作者Jay4902CA
相关产品推荐
相关产品推荐

