鍍金池/ 問(wèn)答/網(wǎng)絡(luò)安全  HTML/ 如何使用localStorage結(jié)合Vuex來(lái)保存用戶登錄信息?

如何使用localStorage結(jié)合Vuex來(lái)保存用戶登錄信息?

我現(xiàn)在有一個(gè) headerBar 組件,上面顯示了用戶名稱(如果設(shè)置了昵稱顯示昵稱,否則顯示用戶名稱),當(dāng)用戶點(diǎn)擊登錄按鈕時(shí),調(diào)用api獲取用戶信息,保存到Vuexstate里面,headerBar通過(guò)this.$store.getters.xxx來(lái)獲取用戶登錄信息,但是當(dāng)用戶刷新時(shí),state里面的用戶信息全沒了,所以我考慮加入 localStorage 來(lái)保存用戶信息,但是這部分代碼不知道該如何“分布”,因?yàn)橐紤]用戶登錄超時(shí),請(qǐng)小伙伴們指點(diǎn)指點(diǎn),謝謝!

代碼如下:

export default new Vuex.Store({
    state: {
        loginInfo: null,//當(dāng)前用戶簡(jiǎn)要信息
    },
    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) => {
                //登錄成功,保存當(dāng)前用戶信息到 state 里面,以便其他組建獲取
                context.commit('SET_LOGININFO', res.data);
                //保存到localStorage里面
                window.localStorage.setItem('loginInfo', JSON.stringify(items));
                return res;                
            })
            .catch(function (error) {});
        },
    }
})

想請(qǐng)教幾個(gè)問(wèn)題:
1、這么使用 localStorage 正確么?或者合理么?有沒有更好的方法呢?
2、在getters下面的GET_LOGININFO方法里面,如果進(jìn)入了if(!loginInfo)語(yǔ)句,該方法是否可以為 state 屬性loginInfo賦值呢(或者調(diào)用mutations方法來(lái)給loginInfo賦值)?
3、這樣的話,如果用戶點(diǎn)擊退出按鈕,是不是意味著需要清空state的loginInfo,還需要清除localStorage下面的loginInfo呢?
4、這樣的話,從客戶端角度來(lái)看,是不是客戶就永遠(yuǎn)保持以登錄狀態(tài)了?這個(gè)環(huán)節(jié)該怎么做好呢?

補(bǔ)充:第二個(gè)問(wèn)題其實(shí)就是:getters里面的方法是否可以為state屬性賦值(直接訪問(wèn)state屬性賦值 或者 調(diào)用mutations方法賦值)?

回答
編輯回答
乖乖噠
  1. 不合理。用戶登錄成功以后應(yīng)該在本地保存一份用戶數(shù)據(jù),注意我說(shuō)的是保存到本地不是保存到localstorage,因?yàn)楸4姹镜氐姆椒ㄓ泻芏喾N,比如cookieindexedDB等,所以,代碼中不應(yīng)該直接調(diào)用window.localStorage,而是應(yīng)該封裝一個(gè)用戶數(shù)據(jù)的讀取類,解除代碼耦合,將來(lái)要改成其他存儲(chǔ)方式比較簡(jiǎn)單:

    const USER_INFO='USER_INFO'
    function getUserinfo(){}
    function setUserinfo(){}
  2. 不應(yīng)該。個(gè)人認(rèn)為不應(yīng)該,getters語(yǔ)義上就是獲取數(shù)據(jù),但是卻改變了數(shù)據(jù),導(dǎo)致不純凈,可能會(huì)埋下維護(hù)上的隱患。

  3. 是的。理論上應(yīng)該有一個(gè)接口用來(lái)更新用戶狀態(tài),比如判斷用戶是否需要重新登錄之類的,比如api/refresh, 所以邏輯應(yīng)該是:

    • 用戶進(jìn)入app,判斷本地是否有用戶信息。

      • 有,調(diào)用api/refresh,判斷是否需要重新登錄。

        • 不需要(連續(xù)登錄),將信息保存在vuex中,并進(jìn)入首頁(yè),往后數(shù)據(jù)讀取全部走vuex。

        • 需要(長(zhǎng)時(shí)間未登錄),刪除本地用戶信息并跳轉(zhuǎn)到登錄流程。

      • 沒有, 跳轉(zhuǎn)到登錄流程(以下是登錄流程)。

        • 調(diào)用api/login登錄。

        • 將保存到本地,并保存到vuex中,往后數(shù)據(jù)讀取全部走vuex。

  4. 看3,具體還可以看看jwt,或者基于tokenapi設(shè)計(jì)相關(guān)的文章。

2017年7月4日 17:54
編輯回答
凹凸曼

思考一些時(shí)間了,我把結(jié)論寫一下,朋友看看是否合理:
1、當(dāng)用戶訪問(wèn)站點(diǎn)時(shí),在路由攔截器里判斷cookie里面是否有username或者token或者sessionId之類的標(biāo)識(shí),有:表示“已登陸”,否則跳轉(zhuǎn)到登陸頁(yè)面;
2、如果已登陸,跳轉(zhuǎn)到相應(yīng)路由,對(duì)應(yīng)頁(yè)面調(diào)用api獲取數(shù)據(jù),如果提示"未登陸",跳轉(zhuǎn)到登陸頁(yè);
3、正常登陸,保持用戶信息到cookie

這個(gè)流程有問(wèn)題么?

2018年3月28日 11:31