我正在尝试使用 firebase 对 Vue.js 应用程序进行身份验证。
我有一个问题,如果在登录时尝试直接访问受登录保护的 URL,路由器将在 firebase.js 有时间返回身份验证响应之前加载并检查身份验证状态。这会导致用户跳转到登录页面(当他们已经登录时)。
如何延迟 vue-router 导航,直到从 firebase 检索到 auth 状态?我可以看到 firebase 将 auth 数据存储在 localStorage 中,检查它是否作为初步身份验证检查是否安全?理想情况下,最终结果是在用户通过身份验证时显示加载微调器或其他内容,然后他们应该能够访问他们导航到的页面。
路由器/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
应用程序.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 始终会在启动时触发身份验证状态更改事件,但不会立即触发。
您需要让 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
,因为这已经由 initializeAuth
promise 处理。
关于javascript - Firebase Auth 和 Vue-router,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43648240/