当前位置: 首页 > 知识库问答 >
问题:

Firebase身份验证和Vue-router

安轶
2023-03-14

我正在尝试使用Firebase验证Vue.js应用程序。

我有一个问题,如果在登录时尝试直接访问受登录保护的URL,路由器将在firebase之前加载并检查身份验证状态。js有时间返回auth响应。这会导致用户被弹回登录页面(当他们已经登录时)。

如何延迟vue-router导航直到从Firebase检索到auth状态?我可以看到Firebase将auth数据存储在local存储中,检查它是否作为初步身份验证检查存在是否安全?理想情况下,最终结果是在用户经过身份验证时显示加载微调器或其他东西,然后他们应该能够访问他们导航到的页面。

路由器/index.js

let router = new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    },
    {
      path: '/login',
      name: 'Login',
      component: Login
    },
    {
      path: '/example',
      name: 'Example',
      component: Example,
      beforeEnter: loginRequired
    }
})

function loginRequired (to, from, next) {
  if (authService.authenticated()) {
    next()
  } else {
    next('/login')
  }
}

认证. js

import * as firebase from 'firebase'

var config = {
    // firebase config
}

firebase.initializeApp(config)

var authService = {

  firebase: firebase,
  user: null,

  authenticated () {
    if (this.user == null) {
      return false
    } else {
      return !this.user.isAnonymous
    }
  },

  setUser (user) {
    this.user = user
  },

  login (email, password) {
    return this.firebase.auth().signInWithEmailAndPassword(email, password)
      .then(user => {
        this.setUser(user)
      })
  },

  logout () {
    this.firebase.auth().signOut().then(() => {
      console.log('logout done')
    })
  }
}

firebase.auth().onAuthStateChanged(user => {
  authService.setUser(user)
})

export default authService

app.vue

<template>
  <div id="app">
    <p v-if="auth.user !== null">Logged in with {{ auth.user.email }}</p>
    <p v-else>not logged in</p>
    <router-view v-if="auth.user !== null"></router-view>
  </div>
</template>

<script>
import authService from './auth'

export default {
  name: 'app',
  data () {
    return {
      auth: authService
    }
  }
}
</script>

共有3个答案

庾勇军
2023-03-14

我只是遇到了同样的问题,并最终将Vue对象的创建延迟到第一个onAuthstatedChanged。

# main.js
// wait for first firebase auth change before setting up vue
import { AUTH_SUCCESS, AUTH_LOGOUT } from "@/store/actions/auth";
import { utils } from "@/store/modules/auth";
let app;
firebase.auth().onAuthStateChanged(async user => {
  if (!app) {
    if (user) {
      await store.dispatch(AUTH_SUCCESS, utils.mapUser(user));
    } else {
      await store.dispatch(AUTH_LOGOUT);
    }
    app = new Vue({
      router,
      store,
      i18n,
      render: h => h(App)
    }).$mount("#app");
  }
});

然后,在我的路线中,我正常检查,如果他们在登录路线中结束,我只需将他们推至我的概述页面,这是我的仪表板页面。

#router.js
router.beforeEach((to, from, next) => {
  let authenticated = store.getters.isAuthenticated;
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    if (!authenticated) {
      next({
        name: "Login",
        query: { redirect: to.fullPath }
      });
    } else {
      next();
    }
  } else {
    // doesn't require auth, but if authenticated already and hitting login then go to overview
    if (authenticated && to.name === "Login") {
      next({
        name: "Overview"
      });
    }
    next(); // make sure to always call next()!
  }
});
龙成仁
2023-03-14

以 Richard 的答案为基础,对于那些使用常规 Vue(不是 Vuex)的人

//initialize firebase
firebase.initializeApp(config);
let app: any;
firebase.auth().onAuthStateChanged(async user => {
if (!app) {
    //wait to get user
    var user = await firebase.auth().currentUser;

    //start app
    app = new Vue({
      router,
      created() {
        //redirect if user not logged in
        if (!user) {
          this.$router.push("/login");
        }
      },
      render: h => h(App)
    }).$mount("#app");
  }
});
//route definitions
//...
router.beforeEach((to, from, next) => {
  const currentUser = firebase.auth().currentUser;
  const requiresAuth = to.matched.some(record => record.meta.requiresAuth);

  if (requiresAuth && !currentUser) {
    const loginpath = window.location.pathname;   
    next({ name: 'login', query: { from: loginpath } });
  } else if (!requiresAuth && currentUser) {
    next("defaultView");
  } else {
    next();
  }
});
林念
2023-03-14

Firebase 总是在启动时触发身份验证状态更改事件,但不会立即触发。

您需要进行<code>authService。authenticated返回一个promise,以便等待Firebase完成其用户/身份验证初始化。

const initializeAuth = new Promise(resolve => {
  // this adds a hook for the initial auth-change event
  firebase.auth().onAuthStateChanged(user => {
    authService.setUser(user)
    resolve(user)
  })
})

const authService = {

  user: null,

  authenticated () {
    return initializeAuth.then(user => {
      return user && !user.isAnonymous
    })
  },

  setUser (user) {
    this.user = user
  },

  login (email, password) {
    return firebase.auth().signInWithEmailAndPassword(email, password)
  },

  logout () {
    firebase.auth().signOut().then(() => {
      console.log('logout done')
    })
  }
}

您不需要从SignInwith…promise调用setUser,因为这已经由初始化认证promise处理。

 类似资料:
  • 我一直很难找到Google Firebase身份验证背后的SLA。根据托管和实时数据库的服务水平协议,Firebase的每月正常运行时间百分比应至少达到99.95%。它是否适用于身份验证服务?

  • 在本章中,我们将匿名认证用户。 步骤1 - 启用匿名身份验证 这和我们以前的章节是一样的。需要打开Firebase信息中心,点击侧边菜单中的Auth和标签栏内的认证方法,需要启用匿名身份验证。 第2步 - 登录功能 可以使用方法进行此认证。 示例 让我们来看看下面的例子,参考示例代码 -

  • 使用,https://github.com/firebase/FirebaseUI-Android/tree/master/codelabs/chat作为登录的参考,我在键入时似乎遇到了问题 我只能键入Auth的提供者,而不能键入,为什么会这样,它提示我键入社会提供者。

  • 问题内容: 我正在尝试将我的电话号码与我的电子邮件密码身份验证相关联。所以我使用以下步骤建立我的注册: 用户输入电子邮件地址和密码。 然后我打电话 那么我需要将当前帐户与电话号码相关联,因此我正在使用 但是,我没有看到任何链接。在我的Firebase控制台中创建的2个帐户和当前用户的详细信息中只有电话号码。当我再次使用电子邮件和密码登录并检查用户详细信息时,电话号码不存在! 请在下面找到我的代码:

  • Flutter Android Firebase认证错误,虽然应用程序没有失败,但认证通过了,但终端出错 [错误:flatter/lib/ui/ui\u dart\u state.cc(148)]未处理的异常:NoSuchMethodError:对null调用了getter“uid”。 错误似乎来自这一行代码

  • keytool-list-v-keystore my_keystore.jks