我的应用程序使用Firebase API进行用户身份验证,将登录状态另存为Vuex状态中的布尔值。
当用户登录时,我设置了登录状态并相应地显示“登录/注销”按钮。
但是刷新页面后,vue应用程序的状态将丢失并重置为默认状态
这会导致出现问题,因为即使用户登录并刷新页面,登录状态也将被设置为false,即使用户保持登录状态,也会显示登录按钮而不是退出按钮。
我应该怎么做才能防止这种行为
我应该使用Cookie 还是可以使用其他更好的解决方案...
-
--
我的应用程序使用Firebase API进行用户身份验证,将登录状态另存为Vuex状态中的布尔值。
当用户登录时,我设置了登录状态并相应地显示“登录/注销”按钮。
但是刷新页面后,vue应用程序的状态将丢失并重置为默认状态
这会导致出现问题,因为即使用户登录并刷新页面,登录状态也将被设置为false,即使用户保持登录状态,也会显示登录按钮而不是退出按钮。
我应该怎么做才能防止这种行为
我应该使用Cookie 还是可以使用其他更好的解决方案...
Answers:
这是一个已知的用例。有不同的解决方案。
例如,可以使用vuex-persistedstate
。这是一个用于vuex
处理和存储页面刷新之间的状态的插件。
样例代码:
import { Store } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'
const store = new Store({
// ...
plugins: [
createPersistedState({
getState: (key) => Cookies.getJSON(key),
setState: (key, state) => Cookies.set(key, state, { expires: 3, secure: true })
})
]
})
我们在这里做的很简单:
js-cookie
getState
我们尝试从Cookies
setState
我们我们的状态保存到Cookies
创建VueX状态时,请使用vuex-persistedstate插件将其保存到会话存储中。这样,关闭浏览器时信息将丢失。避免使用cookie,因为这些值将在客户端和服务器之间传递。
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex);
export default new Vuex.Store({
plugins: [createPersistedState({
storage: window.sessionStorage,
})],
state: {
//....
}
});
使用sessionStorage.clear();
时,用户手动注销。
vuex-persistedstate.es.js?0e44:1 Uncaught (in promise) TypeError: Converting circular structure to JSON
Vuex状态保留在内存中。页面加载将清除此当前状态。这就是为什么状态在重新加载时不持久的原因。
但是vuex-persistedstate
插件解决了这个问题
npm install --save vuex-persistedstate
现在,将其导入商店。
import Vue from 'vue'
import Vuex from 'vuex'
import account from './modules/account'
import createPersistedState from "vuex-persistedstate";
Vue.use(Vuex);
const store = new Vuex.Store({
modules: {
account,
},
plugins: [createPersistedState()]
});
只需一行代码即可完美工作: plugins: [createPersistedState()]
我认为使用Cookies / localStorage保存登录状态在某些情况下可能会导致一些错误。
Firebase已经在localStorage上记录了登录信息,其中包括expirationTime和refreshToken。
因此,我将使用Vue创建的钩子和Firebase api来检查登录状态。
如果令牌已过期,则api将为我们刷新令牌。
因此,我们可以确保在应用程序中显示的登录状态等于Firebase。
new Vue({
el: '#app',
created() {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
log('User is logined');
// update data or vuex state
} else {
log('User is not logged in.');
}
});
},
});
我已经解决了这个问题,每次重新加载时都会重置标头,以获取用户数据,但我不知道哪个更好。
new Vue({
el: 'vue',
render: h => h(VueBox),
router,
store,
computed: {
tokenJWT () {
return this.$store.getters.tokenCheck
},
},
created() {
this.setAuth()
},
methods:
Object.assign({}, mapActions(['setUser']), {
setAuth(){
if (this.tokenJWT) {
if (this.tokenJWT === 'expired') {
this.$store.dispatch('destroyAuth')
this.$store.dispatch('openModal')
this.$store.dispatch('setElModal', 'form-login')
} else {
window.axios.defaults.headers.common = {
'Accept': 'application/json',
'Authorization': 'Bearer ' + this.tokenJWT
}
axios.get( api.domain + api.authApi )
.then(res => {
if (res.status == 200) {
this.setUser( res.data.user )
}
})
.catch( errors => {
console.log(errors)
this.destroyAuth()
})
}
}
}
})
})