使用Vuex和Vuex-persistedstate自动登录 [英] Auto SignIn with Vuex and Vuex-persistedstate
问题描述
页面刷新后,我想向auto-sign-in
用户发送信息.我读过我应该使用vuex-persistedstate
将token
保留在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:
这篇关于使用Vuex和Vuex-persistedstate自动登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!