注销时 vuex 为空状态

vuex empty state on logout

我的问题的简要说明:

  1. 页面加载时绝对没有数据存储在我的 vuex 状态
  2. 如果用户已登录(或信息存储在 window.localStorage 中并因此自动登录)我的 vuex 存储从需要身份验证的套接字中检索所有信息。
  3. 然后用户注销了,但是我的vuex state save还是保留了所有的数据

这将是一个安全问题,因为未登录的人(或黑客)在 public 电脑上可以查看用户注销前的状态。

我看过How to clear state in vuex store? 但我觉得这是一种 hack,应该避免。

我目前的解决方案是使用 location.reload();

刷新页面

Is there a better way to prevent this data leak?

正常方法

如果用户登录,那么您可以添加一些布尔标志以确保用户已 loggedin/loggedout。

所以最初的方法是 -

this.$store.commit('insertToken', {realtoken, isLoggedIn: true})

在vuex中比,

insertToken (state, payload) {
  state.token = payload.realtoken
  state.isLoggedIn = payload.isLoggedIn
  localStorage.setItem('token', payload.realtoken)
}

并且当用户注销时,您应该将所有标志设置为 false, 在组件中 -

logout () {
    this.$store.commit('logOut')
    this.$router.replace('/login')
  }

在 vuex 中,

logOut (state, payload) {
  state.token = null
  state.isLoggedIn = false
  localStorage.setItem('token', null)
},

因此,通过 isLoggedIntoken,您可以使用名为 Navigation Guards

的术语告诉路由器导航到哪里

示例 -

const checkToken = () => {

if ((localStorage.getItem('token') == null) || 
 (localStorage.getItem('token') == undefined)) {
  return false
 } else {
   return true
 }
}

// Navigation guards
if (to.path === '/') {
 if (checkToken()) {
   next()
 } else {
  router.push('/login')
 }

}

这是我在通过使用 token 作为与 Vuex 交互的一部分来完成身份验证时使用的方式。

存储在 Vue 中的所有 对象 充当 observable。因此,如果一个值的 referencechanged/mutated 它会触发 实际值也被更改 .

因此,为了重置状态,初始存储模块必须复制为一个值.

在用户注销时,必须为每个模块分配相同的值作为副本。

这可以通过以下方式实现:

// store.js

// Initial store with modules as an object
export const initialStoreModules = {
    user,
    recruitment,
};

export default new Vuex.Store({
    /**
     * Assign the modules to the store 
     * using lodash deepClone to avoid changing the initial store module values
     */
    modules: _.cloneDeep(initialStoreModules),
    mutations: {
        // reset default state modules by looping around the initialStoreModules
        resetState(state) {
        _.forOwn(initialStoreModules, (value, key) => {
            state[key] = _.cloneDeep(value.state);
        });
        },
    }
});

然后在用户注销时调用commit("resetState");

这个扩展做得很好 https://www.npmjs.com/package/vuex-extensions

安装后我可以在 Vuex Logout Action 中调用 reset

logout(context) {
  
    // do the logout stuff, such as 
    context.commit("setUser", {});

    // On logout, clear all State, using vuex-extensions
    this.reset();

    // if using router, change to login page   
    router.replace("/login");
  }

这可能晚了,但我发现 window.localStorage.removeItem('vuex') 很有用。感谢 Thomas von Deyen,https://github.com/championswimmer/vuex-persist/issues/52#issuecomment-413913598