刷新页面后,我想auto-sign-in
用户。我已经读过我应该使用vuex-persistedstate
将token
保留在localstorage
中。这是我的vuex
商店:
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
动作,其中我用newUser
创建了一个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()
中,我想检查令牌是否有效,然后-登录用户。
created() {
let token = localStorage.getItem('user_token')
if(token) {
this.$store.dispatch('autoSignIn', token)
}
}
最后一部分不起作用,我知道我应该使用getState, setState
中的createPersistedState
,但是我不知道该怎么做。我该如何运作?
答案 0 :(得分:1)
如果使用vuex-persistedstate的唯一用例是记住访问令牌,那么您应该首先避免使用它,并从最终构建文件中节省几Kb。
如果要向用户提供离线体验,使用它会更有意义。
如果您所做的全部是将state.user设置为本地存储的令牌,那么您就可以这样做。
// 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,
}
每当刷新页面且商店处于实例化状态时,用户将使用本地存储的令牌作为默认值,如果缺少/未定义,则将其为空
但是如果我是你,我会取代
const state = {
user: null
};
与
const state = {
accessToken: null
};
由于您存储的只是accessToken而不是用户本身,因此其类型具有误导性。
我可以想到3种方式。
首先将状态更改为
const userToken = JSON.parse(window.localStorage.getItem('user_token'));
const state = {
accessToken: userToken ? userToken.token || null : null,
user: null,
};
然后
在App.vue组件上,添加如下所示的已安装方法
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突变存储接收到的用户
如果您有路由器,并且只需要在某些路由上检查经过身份验证的用户,则可以使用路由保护器。例如
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();
},
},
...
],
});
这是我最近学到的一种方法。
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]
});
您可以通过以下方法了解更多信息: