You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vue的beforeEach路由守卫中基于Firebase v9实现登录态校验

问题根源
  • 你封装的userAuthState是同步返回逻辑,而Firebase的onAuthStateChanged是异步回调方法,回调执行前函数就已经返回了初始值null,且该方法没有返回Promise,加await也不会生效。
  • 路由守卫逻辑存在两处错误:一是await !userAuthState()的写法优先级错误,!优先级高于await,会先对返回的null取反得到true再await,导致判断逻辑完全失效;二是每次守卫执行重复调用两次鉴权方法,且错误判断会触发反复跳转形成死循环,导致console.log重复打印、页面无法正常跳转。
正确实现方案

第一步:修正鉴权状态封装方法

将方法改造为返回Promise,同时添加状态缓存避免重复监听造成内存泄漏:

// src/backend/firebase-config.js
import { onAuthStateChanged } from "firebase/auth";
import { auth } from "./你的firebase初始化配置路径";

// 全局缓存用户状态,避免重复监听
let cachedUser = null;

export const getUserAuthState = () => {
  return new Promise((resolve) => {
    // 已有缓存直接返回,减少性能消耗
    if (cachedUser !== null) {
      return resolve(cachedUser);
    }
    // 监听auth状态变更,拿到结果后取消监听
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      cachedUser = user || null;
      unsubscribe();
      resolve(cachedUser);
    });
  });
};

第二步:修正路由全局前置守卫逻辑

单次获取用户状态后再做判断,避免死循环:

import { createRouter, createWebHistory } from 'vue-router'
import { getUserAuthState } from 'src/backend/firebase-config';

// 路由配置示例,注意meta参数的定义
const routes = [
  { 
    path: '/login', 
    component: () => import('@/views/Login.vue'), 
    meta: { requiresAuth: 'login' } // 登录页标记
  },
  { 
    path: '/dashboard', 
    component: () => import('@/views/Dashboard.vue'), 
    meta: { requiresAuth: true } // 需要登录鉴权的页面标记
  },
  { path: '/', component: () => import('@/views/Home.vue') }
]

const Router = createRouter({
  history: createWebHistory(),
  routes
})

Router.beforeEach(async (to, from, next) => {
  // 单次获取用户状态,避免重复调用
  const currentUser = await getUserAuthState();

  // 访问需要鉴权的页面且用户未登录,跳转登录页
  if (to.meta.requiresAuth === true && !currentUser) {
    next({ path: '/login', query: { redirect: to.fullPath } })
  } 
  // 访问登录页且用户已登录,跳转首页
  else if (to.meta.requiresAuth === 'login' && currentUser) {
    next({ path: '/' })
  } 
  // 其余场景正常放行
  else {
    next()
  }
})

export default Router
补充说明

如果项目中使用了Pinia/Vuex等状态管理工具,可以将获取到的用户状态存入全局store共享,后续业务逻辑无需重复调用鉴权方法。

内容的提问来源于stack exchange,提问作者ibrahim farhat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 13:06:09