Firebase Vue.js:如何保护登录组件不受已验证用户的攻击

Firebase Vue.js:如何保护登录组件不受已验证用户的攻击,firebase,vue.js,firebase-authentication,vue-router,Firebase,Vue.js,Firebase Authentication,Vue Router,我正在设计一个应用程序,其中使用firebase auth实现auth。我已经保护用户组件不受未经身份验证的用户的攻击。但是我现在想保护登录组件不受经过身份验证的用户的攻击。到目前为止我已经试过了。这是我的路由器/index.js import Vue from 'vue' import VueRouter from 'vue-router' import { fb } from "@/firebase/init"; import Home from '@/views/Home' Vue.

我正在设计一个应用程序,其中使用firebase auth实现auth。我已经保护用户组件不受未经身份验证的用户的攻击。但是我现在想保护登录组件不受经过身份验证的用户的攻击。到目前为止我已经试过了。这是我的路由器/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import {
  fb
} from "@/firebase/init";
import Home from '@/views/Home'

Vue.use(VueRouter)

const routes = [{
    path: '/',
    name: "home",
    component: Home
  },
  {
    path: '/login',
    name: 'login',
    component: () => import('@/components/auth/Login'),
    meta: {
      alreadyAuth: true
    }
  },
  {
    path: '/signup',
    name: 'signup',
    component: () => import('@/components/auth/Signup'),

  },
  {
    path: '/user/:id',
    name: 'user',
    component: () => import('@/components/user/User'),
    meta: {
      requiresAuth: true
    }
  },

]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

router.beforeEach((to, from, next) => {
  let user = fb.auth().currentUser
  if (to.matched.some(rec => rec.meta.requiresAuth)) {
    if (user) {
      next()
    } else {
      next({
        name: 'login'
      })
    }
  } else if (to.matched.some(rec => rec.meta.alreadyAuth)) {
    if (user) {
      next({
        name: 'user'
      })
    } else {
      next()
    }
  } else {
    next()
  }
})

export default router
还有一个问题是,当我通过身份验证并刷新用户组件时,它会将我重定向回登录组件。为什么会这样


提前谢谢,因为我不知道你的
main.js
,这只是一个假设,但我认为
currentUser
未定义的。您应该记录
user
,并检查它是否在页面加载中定义。Firebase的行为是异步的,所以为了准备好一切,您需要将整个应用程序包装在Firebase回调中

firebase.auth().onAuthStateChanged(() => {
    new Vue({
      router,
      render: h => h(App)
    }).$mount('#app');
});

否则,
currentUser
可能尚未初始化。

因此,您希望阻止登录用户点击您的登录路径,但也希望阻止未登录用户点击Vue应用程序中的某些页面。非常标准的用例。我是如何实现它的:

首先,我的路线有元标记
requireauth
供访客使用。如果用户登录并尝试点击forVisitors路径,我会将用户返回主页(
routeObject.path='/'
,在下面的示例中)。如果用户未登录,并试图点击
requireauth
路径,我会将他们踢到/login。我发现这种方法对于路线构建非常灵活

我的路由器需要知道什么是登录用户。使用Firebase的auth模块,我可以订阅
onAuthStateChanged
,并确定用户是否从第一次发射开始登录

注意,我将当前用户存储在VueX存储中(
store.state.userModule.user
),如果不这样做,您可以忽略该位。此外,我还将Firebase Auth对象作为
store.state.userModule.Auth
存储在我的存储中,因此当您看到它时,它与Firebase Auth相同

此外,您可以在此处找到有关我为何将onAuthStateChanged订阅包装在Promise中的更多详细信息:


const路由器=新路由器({
/*forVisitors路径示例*/
{
路径:'/Login',
名称:'登录',
组件:登录,
元:{
requiresAuth:false,
游客:真的
}
},
/*requireAuth路径的示例*/
{
路径:'/Submit/:mode?/:primary?/:secondary?',
名称:“提交”,
组成部分:提交,
道具:没错,
元:{
真实的
}
}
});
路由器.beforeach(异步(到、从、下一个)=>{
/*检查my store中的用户,或回退到Firebase auth()用户*/
让当前用户=
store.state.userModule.user||
(等待新的承诺((决议)=>{
store.state.userModule.auth().onAuthStateChanged(用户=>{
解析(用户);
});
}));
const requiresAuth=to.meta.requiresAuth;
const forVisitors=to.meta.forVisitors;
常量routeObject={};
if(适用于访客和当前用户){
routeObject.path='/';
}else if(requireAuth&&!currentUser){
routeObject.path='/login';
}
下一步(routeObject);
});