[英]Pattern for Firebase onAuthStateChanged and Navigation Guards - Quasar app
我在我的 Quasar 應用程序中遇到有關瀏覽器刷新和 Firebase 身份驗證的問題。
在用戶登錄並點擊瀏覽器刷新后, firebase.auth().currentUser
返回 null(因為這是異步執行的)。 這意味着當beforeEach
被執行時, currentUser
是 null 並且用戶被提示登錄頁面。 但是我看到當調用onAuthStateChanged
的回調時,用戶設置正確。
在 Quasar 應用程序中,是否有任何模式可以在導航過程中使用onAuthStateChanged
以便重復使用現有用戶 session?
// Vue-router => index.js
firebase.auth().onAuthStateChanged(user => {
console.log('onAuthStateChanged Invoked => ' + user);
});
router.beforeEach((to, from, next) => {
let currentUser = firebase.auth().currentUser;
let requiresAuth = to.matched.some(record => record.meta.requiresAuth);
if (requiresAuth && !currentUser) {
next('signin');
} else {
if (requiresAuth && currentUser.emailVerified === false) {
next('signin');
} else {
next();
}
}
});
在您的main.js
,您應該監聽onAuthStateChange
。
import Vue from 'vue'
import App from './App'
import router from './router'
import firebase from 'firebase'
Vue.config.productionTip = false
let app;
let config = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_PROJECT_ID.firebaseapp.com",
databaseURL: "https://YOUR_PROJECT_ID.firebaseio.com",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_PROJECT_ID.appspot.com",
messagingSenderId: "YOUR_MESSAGING_SEND_ID"
};
firebase.initializeApp(config)
firebase.auth().onAuthStateChanged(function(user) {
if (!app) {
/* eslint-disable no-new */
app = new Vue({
el: '#app',
template: '<App/>',
components: { App },
router
})
}
});
只有當我們確定 Firebase Auth 對象可以使用時,我們才會初始化應用程序。
我直接在我的路由器防護中使用 firebase.auth().onAuthStateChanged 函數,如下所示:我檢查路由是否需要經過身份驗證的用戶(可選),然后加載當前登錄的用戶並將其提交到我的 Vuex 存儲中。 這樣當前登錄的用戶在路由守衛檢查訪問之前處於我的 Vuex 狀態。 否則,特別是在頁面重新加載后,用戶尚未加載,守衛重定向到登錄頁面......
...
Router.beforeEach((to, from, next) => {
let requiresAuth = to.matched.some(record => record.meta.requiresAuth)
// If route requires auth --> load auth state first from firebase
if (requiresAuth) {
firebase.auth().onAuthStateChanged(user => {
store.commit("user/SET_USER", user);
let currentUser = firebase.auth().currentUser
store.commit("user/SET_USER_FULL", currentUser);
user.getIdToken().then(token => {
store.commit("user/SET_TOKEN", token)
});
if (!user) next('login')
else next();
});
} else next()
})
export default Router
我使用類星體。 這段代碼在我的路由器/index.js 中。 不要忘記像這樣導入您的商店:從'../store'導入商店
我再次重構了整個路由器/授權。 將代碼移至 ./boot/firebase.js。
export default async ({ router, store }) => {
// Here goes the firebase.initializeApp(firebaseConfig);
// ...
const getCurrentUser = () => {
return new Promise((resolve, reject) => {
const unsubscribe = firebase.auth().onAuthStateChanged((userFirebase) => {
// Do some store stuff...
store.commit("user/SET_USER", userFirebase);
unsubscribe();
resolve(userFirebase);
}, reject);
});
}
router.beforeEach(async (to, from, next) => {
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
if (requiresAuth && !await getCurrentUser()){
next({ name: 'login' });
} else if (!from.name) {
// Load user also on a full page reload on pages which do not require auth...
await getCurrentUser();
next();
} else {
next();
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.