Vue.js:如何保护登录组件免受经过身份验证的用户的影响

Posted

技术标签:

【中文标题】Vue.js:如何保护登录组件免受经过身份验证的用户的影响【英文标题】:Vue.js: How to protect login component from authenticated user 【发布时间】:2020-05-22 16:24:01 【问题描述】:

我正在设计一个使用 firebase-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

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

提前致谢

【问题讨论】:

【参考方案1】:

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

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

否则currentUser可能还没有初始化。

【讨论】:

【参考方案2】:

因此,您希望阻止已登录的用户访问您的登录路径,但您还希望阻止未登录的用户访问您的 Vue 应用程序中的某些页面。非常标准的用例。以下是我的实现方式:

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

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

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

此外,您可以在此处找到有关我将 onAuthStateChanged 订阅包装在 Promise 中的更多详细信息:Getting 'Uncaught' after catching error in firebase.auth() with async


const router = new Router(
    /* example of forVisitors path */
    
        path: '/Login',
        name: 'Login',
        component: Login,
        meta: 
            requiresAuth: false,
            forVisitors: true
        
    ,
    /* example of requiresAuth path */
    
        path: '/Submit/:mode?/:primary?/:secondary?',
        name: 'Submit',
        component: Submit,
        props: true,
        meta: 
            requiresAuth: true
        
    
);

router.beforeEach(async (to, from, next) => 
/* Check for a user in my store, or fallback to Firebase auth() user */
    let currentUser =
        store.state.userModule.user ||
        (await new Promise((resolve) => 
            store.state.userModule.auth().onAuthStateChanged(user => 
                resolve(user);
            );
        ));

    const requiresAuth = to.meta.requiresAuth;
    const forVisitors = to.meta.forVisitors;
    const routeObject = ;

    if (forVisitors && currentUser) 
        routeObject.path = '/';
     else if (requiresAuth && !currentUser) 
        routeObject.path = '/login';
    

    next(routeObject);
);

【讨论】:

以上是关于Vue.js:如何保护登录组件免受经过身份验证的用户的影响的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 IdentityServer4 保护 API(免受意外调用)?

如何在不经过注册用户身份验证的情况下保护公共API请求

如何保护 Web 应用程序免受 cookie 窃取攻击?

CSRF 保护

如何在 Laravel 和 Vue.js 中使用 jwt-auth 检查用户是不是经过身份验证

Laravel CSRF 保护