gpt4 book ai didi

firebase - VueJS + Firebase Auth + Route Guards - 同步问题/竞争条件

转载 作者:行者123 更新时间:2023-12-05 07:29:32 25 4
gpt4 key购买 nike

在将 Firebase Auth 集成到我的 Vue 应用程序中时,我最近偶然发现了一个问题,即在页面刷新时登录的用户不会被识别为已登录(因此在尝试访问 protected 路由时会重定向到登录页面)。
这是因为 firebase.auth().onAuthStateChanged(...) 的初始回调在路由守卫评估状态之前尚未返回。

有几个提议的解决方案,但对我来说似乎没有一个是干净的。最突出的似乎是通过将 new Vue(...).$mount('#app') 移动到 onAuthStateChanged() 中来延迟应用程序的实际安装> 回调。
由于在大多数情况下,初始 View 不需要用户登录(或者可能是登录路由本身),因此不需要延迟整个应用程序的安装,直到 firebase 回调返回。

我想我可能找到了更好的解决方案,但如果您发现此方法有任何问题或可以进一步改进,我将不胜感激。

注意:我使用 Vuex 全局状态存储来管理应用状态。

我在 App 组件的 created 生命周期 Hook 中的 main.js 中初始化 firebase onAuthStateChanged() 回调:

new Vue({
router,
store,
render: h => h(App),
created() {
firebaseApp.auth().onAuthStateChanged((user) => {
if(!this.$store.getters.firebaseInitialized)
this.$store.commit('firebaseInitialized')
if (user) {
if(!this.$store.authenticated || this.$store.getters.loggedInUser.uid != user.uid)
this.$store.dispatch('logIn', user)
}
})
}
}).$mount('#app')

状态中的 firebaseInitialized bool 值跟踪 firebase 的初始状态,默认情况下为 false 并且仅通过以下方式设置为 true第一个 onAuthStateChanged 回调。

router.js 中,我现在创建一个“轮询 promise ”来检查所述 firebaseInitialized 并等待 init 完成(或超时),然后再检查的身份验证状态用户:

function ensureFirebaseIsInitialized() {
let timeout = 5000;
let start = Date.now();
return new Promise(function (resolve, reject) {
(function waitForFirebaseInit(){
if (store.getters.firebaseInitialized)
return resolve();
else if((Date.now() - start) >= timeout)
return reject(new Error('Firebase initialize timeout'))
setTimeout(waitForFirebaseInit, 30);
})();
});
}

现在可以在 router.beforeEach 中使用此 promise:

router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
ensureFirebaseIsInitialized().then(() => {
if(store.getters.authenticated) {
next()
}
else {
next('/login')
}
}).catch((error) => {
console.log('firebase not initialized')
next('/login')
})
}
else {
next()
}
})

这种方法是否存在我没​​有意识到的问题,或者是否可以进一步改进?

最佳答案

在你的 Router.js 文件中简单地添加

router.beforeEach((to,from,next) => {
if(to.matched.some(record => record.meta.auth)){
firebase.auth().onAuthStateChanged((user) => {
if(!user)
{
next({
path: '/'

})
} else {
next()
}
})}else next()
})

这既可以防止页面访问,也可以在用户在页面上时未经授权将其踢出。我自己在我的一个网站上使用它,到目前为止没有遇到任何问题

关于firebase - VueJS + Firebase Auth + Route Guards - 同步问题/竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52686362/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com