Firebase身份验证和Vue路由器 [英] Firebase Auth and Vue-router

查看:74
本文介绍了Firebase身份验证和Vue路由器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Firebase对Vue.js应用进行身份验证.

I'm trying to authenticate a Vue.js app using firebase.

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

I have an issue where if trying to access a login-protected URL directly while logged in, the router will load and check for auth state before firebase.js has time to return the auth response. This results in the user being bounced to the login page (while they are already logged in).

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

How do I delay vue-router navigation until auth state has been retrieved from firebase? I can see that firebase stores the auth data in localStorage, would it be safe to check if that exists as a preliminary authentication check? Ideally the end result would be to show a loading spinner or something while the user is authenticated, then they should be able to access the page they navigated to.

router/index.js

router/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')
  }
}

auth.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>

推荐答案

Firebase总是在启动时触发auth状态更改事件,但不是立即发生的.

Firebase always triggers an auth state change event on startup but it's not immediate.

您需要使authService.authenticated返回承诺,以便等待Firebase完成其用户/身份验证初始化.

You'll need to make authService.authenticated return a promise in order to wait for Firebase to complete its user/auth initialisation.

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...承诺中调用setUser,因为这已经由initializeAuth承诺进行了处理.

You don't need to call setUser from the signInWith... promise as this will already be handled by the initializeAuth promise.

这篇关于Firebase身份验证和Vue路由器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆