【问题标题】:Pattern for Firebase onAuthStateChanged and Navigation Guards - Quasar appFirebase onAuthStateChanged 和 Navigation Guards 的模式 - Quasar 应用
【发布时间】:2018-10-23 17:44:40
【问题描述】:

我的 Quasar 应用程序在浏览器刷新和 Firebase 身份验证方面遇到问题。

在用户登录并单击浏览器刷新后,firebase.auth().currentUser 返回 null(因为它是异步执行的)。这意味着当beforeEach 被执行时,currentUser 为空并且用户被提示登录页面。但是我看到,当调用onAuthStateChanged 的回调时,用户设置正确。

在 Quasar 应用程序中,是否有任何模式可以在导航过程中使用 onAuthStateChanged,以便重复使用现有的用户会话?

// 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();
    }
  }
});

【问题讨论】:

    标签: firebase firebase-authentication quasar-framework


    【解决方案1】:

    在您的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 对象可以使用时,我们才会初始化应用程序。

    【讨论】:

    • 谢谢。我之前看过这个提议。然而,对于 Quasar 应用程序,初始化似乎是由框架完成的。我遇到了一个解决方案(在 VueJS 论坛 - forum.vuejs.org/t/vue-routes-firebase-auth-sync-problem/4470)用 Promise 包装 firebase.auth().currentUser,然后使用 promise 解析来执行 beforeEach 中的逻辑,这似乎是有效的。
    • 同样的代码只是放在 Quasar 启动文件中。
    【解决方案2】:

    我直接在路由器保护中使用 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 中。不要忘记像这样导入您的商店:import store from '../store'

    【讨论】:

      猜你喜欢
      • 2019-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-15
      • 2016-12-29
      • 2021-03-02
      • 2018-02-21
      • 2017-09-22
      相关资源
      最近更新 更多