簡體   English   中英

Firebase onAuthStateChanged 和 Navigation Guards 的模式 - Quasar 應用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM