我用Vue.js,vue-router和firebase创建了一个应用程序。在main.js
文件中,我输入了以下代码:
created() {
firebase.initializeApp({
apiKey: "xxxxxxxxxxx",
authDomain: "xxxxxxx.firebaseapp.com",
databaseURL: "https://xxxxxxxxxx.firebaseio.com",
projectId: "xxxxxxxxxx",
storageBucket: "",
})
firebase.auth().onAuthStateChanged((user) => {
if(user) {
this.$store.dispatch('autoSignIn', user)
}
})
}
这是一个Vue-Store:
state: {
user: null
},
mutations: {
setUser(state, payload) {
state.user = payload
}
},
actions: {
autoSignIn({commit}, payload) {
commit('setUser', {
id: payload.uid
})
}
}
在vue-router中,我确保在继续访问根目录之前,检查用户是否已获得授权。如果没有,请将其重定向到登录页面。在登录页面中,它会检查用户是否已获得授权。如果没有,则重定向到根目录。所以,我登录了,我在根目录中。我重新加载页面,我立即重定向到登录页面,并立即重定向到根目录,没有其他任何事情发生。这一切都发生在1秒内,看起来很难看。
答案 0 :(得分:2)
firebase.auth().onAuthStateChanged()
是异步的。因此,当我们能够访问user
时,正在执行路线防护。这就是您被重定向到登录页面的原因。
到那时异步调用已经完成,我们可以访问user
。由于您在登录页面中检查user
,现在user
可用,您将被踢回根路径。
默认情况下,Firebase会在密钥localStorage
下的'firebase:authUser'
内存储一个令牌,以保留auth state persisted 。
因此,您可以检查路线保护中的localStorage
是否存在此密钥
router.beforeEach((to, from, next) => {
//check local storage
let loccalStorageKeys = Object.keys(window.localStorage);
const firebaseAuthUser = loccalStorageKeys.filter(item => item.startsWith('firebase:authUser'))[0];
if(firebaseAuthUser){
next();
}else{{
next('/login');
}}
})
由于检查是同步的,因此应该阻止跳转重定向。
或者替代方法是使用名为user
的vuex插件来保持与vuex-persistedstate
对应的vuex状态。然后检查user
状态以保护路线。然后,当用户注销时清除user
状态。查看有关vuex-persisted状态的post。
从firebase v4.12.0开始,auth状态持久性(对于LOCAL持久性)从本地存储移动到indexedDB。
由于这是firebase的内部实现,并且可能在将来发生变化,因此依赖于检查本地存储中是否存在firebase:authUser
以确认用户的登录状态不是一个好主意。
所以最好坚持上面替代方法中提到的用户数据并使用它来检查用户是否已登录