使用Vuex和Vuex-persistedstate自动登录 [英] Auto SignIn with Vuex and Vuex-persistedstate

查看:480
本文介绍了使用Vuex和Vuex-persistedstate自动登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

页面刷新后,我想向auto-sign-in用户发送信息.我读过我应该使用vuex-persistedstatetoken保留在localstorage中.这是我的vuex商店:

I would like to auto-sign-in user when the page has been refreshed. I've read that I should use vuex-persistedstate to persist the token in localstorage. Here's my vuex store:

store: {
    user: null
},
actions: {
    autoSignIn ({commit}, payload) {
      commit('setUser', { id: payload.token })
    }
},
mutations: {
    setUser (state, payload) {
      state.user = payload;
    }
},
plugins: [ createPersistedState({
  getState: (key) => localStorage.getItem(key),
  setState: (key, state) => localStorage.setItem('user_token', key)
 }) ]

我也有signIn动作,我用token创建了newUser.

I also have signIn action where I create a newUser with token.

signUserIn ({commit, getters, state}, payload) {
  let data = {
    _username: payload.email,
    _password: payload.password
  }
  Vue.http.post(
    'url',
      data,
    { channel: 'default' },
    { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
  ).then(response => {
      const newUser = {
        id: response.body.token
      }
      localStorage.setItem('user_token', response.body.token)
      commit('setUser', newUser)
  })
}

然后在main.js-created()中,然后检查令牌是否有效-登录用户.

Then in main.js - created() I would like to check if the token is valid, afterwards - sign user in.

created() {
    let token = localStorage.getItem('user_token')
    if(token) {
      this.$store.dispatch('autoSignIn', token)
    }
}

最后一部分不起作用,我知道我应该使用createPersistedState中的getState, setState,但我不知道该怎么做.我该如何运作?

The last part doesn't work, I know I should use getState, setState from createPersistedState but I have no idea how to do it. How do I make it work?

推荐答案

如果使用vuex-persistedstate的唯一用例是记住访问令牌,那么您应该首先避免使用它,并为自己节省一些Kb.最终的构建文件.

If the only use case for using vuex-persistedstate is to remember the access token then you should avoid using it in the first place and save yourself a few Kb from the final build file.

如果要向用户提供脱机体验,则使用它会更有意义.

It would make more sense using it if you were to provide offline experience to your users.

如果您所做的全部是将state.user设置为本地存储的令牌,那么您就可以这样做.

If all you do is set state.user with the locally stored token then you could just do.

// if localStorage contains a serialized object with a 'token' attribute
const userToken = JSON.parse(window.localStorage.getItem('user_token'));

const state = {
    user: userToken ? userToken.token || null : null
};

const mutations = {};
const actions = {};

export default {
   state,
   mutations,
   actions,
}

每当刷新页面且商店处于实例化状态时,用户将使用本地存储的令牌作为默认值,如果缺少/未定义,则将其为空

Whenever you refresh the page and the store is being instantiated state.user will either take as default value the locally stored token or null if missing/undefined

但是如果我是你,我会取代

However if i were you i would replace

const state = {
    user: null
};

const state = {
    accessToken: null
};

由于您存储的只是accessToken而不是用户本身,因此其类型具有误导性.

since all you store is the accessToken and not the user itself so its kind misleading.

我可以想到3种方式.

首先将状态更改为

const userToken = JSON.parse(window.localStorage.getItem('user_token'));

const state = {
    accessToken: userToken ? userToken.token || null : null,
    user: null,
};

然后

在App.vue组件上,添加如下所示的已安装方法

on your App.vue component add a mounted method like the following

import { mapState, mapActions } from 'vuex';

export default {
    ...
    computed: {
        ...mapState([
           'accessToken',
           'user',
        ])
    },
    mounted() {
        if (this.accessToken && !this.user)
            this.getAuthUser();
    },
    methods: {
        ...mapActions([
            'getAuthUser',
        ]),
    },
}

因此,在每次刷新时,安装了App时,我们都有一个accessToken但没有一个用户,我们调用getAuthUser()操作,该操作进行ajax调用,并以setUser突变形式存储接收到的用户

So on every refresh when the App is mounted and we have an accessToken but not a user we call getAuthUser() action which makes an ajax call and stores the received user with a setUser mutation

如果您有路由器,并且只需要在某些路由上检查经过身份验证的用户,则可以使用路由保护器.例如

If you have a router and you only need to check for an authenticated user on certain routes then you can use route guards. for example

import store from '@/store';

export default new Router({
    routes: [
        ...
        {
            path: '/admin',
            component: Admin,
            beforeEnter: (to, from, next) => {
                if (!store.state.accessToken) return next('/login');
                if (store.state.accessToken && !store.state.user) {
                    return store.dispatch('getAuthUser')
                        .then(() => {
                            // user was retrieved and stored and
                            // we can proceed
                            next();
                        })
                        .catch(() => {
                            // we couldn't fetch the user maybe because the token
                            // has expired.
                            // We clear the token
                            store.commit('accessToken', null);

                            // And go to login page
                            next('/login');
                        });
                },
                return next();
            },
        },
        ...
    ],
});

使用Vuex插件

这是我最近学到的一种方法.

Using Vuex plugins

This is a method I've recently learned.

const storeModerator = (store, router) {
    // listen to mutations
    store.subscribe(({ type, payload }, state) => {
        // if commit('setAccessToken') was called dispatch 'getAuthUser'
        if (type === 'setAccessToken') {
            store.dispatch('getAuthUser');
        }
    });
};

export default new Vuex.Store({
    ...,
    plugins: [storeModerator]
});

您可以通过查看以下内容了解更多信息:

You can learn more by checking:

Vue路由器导航卫士

Vuex插件

将Vuex模块与调解器模式解耦

这篇关于使用Vuex和Vuex-persistedstate自动登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆