如何使用localStorage结合Vuex来保存用户登录信息?

我现在有一个 headerBar 组件,上面显示了用户名称(如果设置了昵称显示昵称,否则显示用户名称),当用户点击登录按钮时,调用api获取用户信息,保存到Vuexstate里面,headerBar通过this.$store.getters.xxx来获取用户登录信息,但是当用户刷新时,state里面的用户信息全没了,所以我考虑加入 localStorage 来保存用户信息,但是这部分代码不知道该如何“分布”,因为要考虑用户登录超时,请小伙伴们指点指点,谢谢!

代码如下:

export default new Vuex.Store({
    state: {
        loginInfo: null,//当前用户简要信息
    },
    getters: {
        GET_LOGININFO(state) {
            //先从state里面获取用户登录信息
            let loginInfo = state.loginInfo;
            //如果 state 里面获取不到,那么从localStorage里面获取
            if(!loginInfo){
                loginInfo = JSON.parse(window.localStorage.getItem('loginInfo') || null)
            }
            return loginInfo;
        },
    },
    mutations: {
        SET_LOGININFO(state, data){
            state.userInfo = data.data;
        }
    },
    actions: {
        Login(context, data) {
            axios.post('/api/login', {
                userName: 'admin',
                pwd: '123456'
            })
            .then((res) => {
                //登录成功,保存当前用户信息到 state 里面,以便其他组建获取
                context.commit('SET_LOGININFO', res.data);
                //保存到localStorage里面
                window.localStorage.setItem('loginInfo', JSON.stringify(items));
                return res;                
            })
            .catch(function (error) {});
        },
    }
})

想请教几个问题:
1、这么使用 localStorage 正确么?或者合理么?有没有更好的方法呢?
2、在getters下面的GET_LOGININFO方法里面,如果进入了if(!loginInfo)语句,该方法是否可以为 state 属性loginInfo赋值呢(或者调用mutations方法来给loginInfo赋值)?
3、这样的话,如果用户点击退出按钮,是不是意味着需要清空state的loginInfo,还需要清除localStorage下面的loginInfo呢?
4、这样的话,从客户端角度来看,是不是客户就永远保持以登录状态了?这个环节该怎么做好呢?

补充:第二个问题其实就是:getters里面的方法是否可以为state属性赋值(直接访问state属性赋值 或者 调用mutations方法赋值)?

阅读 49.2k
2 个回答
  1. 不合理。用户登录成功以后应该在本地保存一份用户数据,注意我说的是保存到本地不是保存到localstorage,因为保存本地的方法有很多种,比如cookieindexedDB等,所以,代码中不应该直接调用window.localStorage,而是应该封装一个用户数据的读取类,解除代码耦合,将来要改成其他存储方式比较简单:

    const USER_INFO='USER_INFO'
    function getUserinfo(){}
    function setUserinfo(){}
  2. 不应该。个人认为不应该,getters语义上就是获取数据,但是却改变了数据,导致不纯净,可能会埋下维护上的隐患。

  3. 是的。理论上应该有一个接口用来更新用户状态,比如判断用户是否需要重新登录之类的,比如api/refresh, 所以逻辑应该是:

    • 用户进入app,判断本地是否有用户信息。

      • 有,调用api/refresh,判断是否需要重新登录。

        • 不需要(连续登录),将信息保存在vuex中,并进入首页,往后数据读取全部走vuex

        • 需要(长时间未登录),删除本地用户信息并跳转到登录流程。

      • 没有, 跳转到登录流程(以下是登录流程)。

        • 调用api/login登录。

        • 将保存到本地,并保存到vuex中,往后数据读取全部走vuex

  4. 看3,具体还可以看看jwt,或者基于tokenapi设计相关的文章。

思考一些时间了,我把结论写一下,朋友看看是否合理:
1、当用户访问站点时,在路由拦截器里判断cookie里面是否有username或者token或者sessionId之类的标识,有:表示“已登陆”,否则跳转到登陆页面;
2、如果已登陆,跳转到相应路由,对应页面调用api获取数据,如果提示"未登陆",跳转到登陆页;
3、正常登陆,保持用户信息到cookie

这个流程有问题么?

推荐问题