不寻常的重定向
Unusual redirects
我使用 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 商店:
state: {
user: null
},
mutations: {
setUser(state, payload) {
state.user = payload
}
},
actions: {
autoSignIn({commit}, payload) {
commit('setUser', {
id: payload.uid
})
}
}
在vue-router中,我确保在进入根目录之前,它会检查用户是否被授权。如果没有,将其重定向到登录页面。在登录页面,它检查用户是否被授权。如果没有则重定向到根目录。因此,我已登录并位于根目录中。我重新加载页面并立即重定向到登录页面并立即重定向到根目录,没有其他任何事情发生。这一切都发生在1秒内,而且看起来很丑
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');
}}
})
由于检查是同步的,因此应该可以防止跳转。
或者另一种方法是使用名为 vuex-persistedstate
的 vuex 插件来持久化对应于 user
的 vuex 状态。然后检查 user
状态以保护路由。然后当用户注销时清除 user
状态。查看此 关于 vuex-persisted 状态。
注意:
自 firebase v4.12.0 起,身份验证状态持久性(对于 LOCAL 持久性)已从本地存储移动到 indexedDB。
由于这是 firebase 的内部实现,将来可能会发生变化,因此依靠检查本地存储中是否存在 firebase:authUser
来确认用户的登录状态并不是一个好主意。
所以最好像上面的替代方法中提到的那样保留用户数据,并用它来检查用户是否登录
我使用 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 商店:
state: {
user: null
},
mutations: {
setUser(state, payload) {
state.user = payload
}
},
actions: {
autoSignIn({commit}, payload) {
commit('setUser', {
id: payload.uid
})
}
}
在vue-router中,我确保在进入根目录之前,它会检查用户是否被授权。如果没有,将其重定向到登录页面。在登录页面,它检查用户是否被授权。如果没有则重定向到根目录。因此,我已登录并位于根目录中。我重新加载页面并立即重定向到登录页面并立即重定向到根目录,没有其他任何事情发生。这一切都发生在1秒内,而且看起来很丑
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');
}}
})
由于检查是同步的,因此应该可以防止跳转。
或者另一种方法是使用名为 vuex-persistedstate
的 vuex 插件来持久化对应于 user
的 vuex 状态。然后检查 user
状态以保护路由。然后当用户注销时清除 user
状态。查看此
注意:
自 firebase v4.12.0 起,身份验证状态持久性(对于 LOCAL 持久性)已从本地存储移动到 indexedDB。
由于这是 firebase 的内部实现,将来可能会发生变化,因此依靠检查本地存储中是否存在 firebase:authUser
来确认用户的登录状态并不是一个好主意。
所以最好像上面的替代方法中提到的那样保留用户数据,并用它来检查用户是否登录