vue3部分页面路由不参与token鉴权

发布于:2025-07-02 ⋅ 阅读:(32) ⋅ 点赞:(0)

在 Vue3 项目中,通常需要对路由进行权限控制,但某些页面(如登录页、注册页、404页面等)不需要进行 Token 鉴权。以下是实现这一功能的几种方法:

方法一:使用路由元信息(meta)

// router/index.js
import { createRouter, createWebHistory } from 'vue-router'

const routes = [
  {
    path: '/login',
    name: 'Login',
    component: () => import('@/views/Login.vue'),
    meta: {
      requiresAuth: false // 不需要鉴权
    }
  },
  {
    path: '/dashboard',
    name: 'Dashboard',
    component: () => import('@/views/Dashboard.vue'),
    meta: {
      requiresAuth: true // 需要鉴权
    }
  }
]

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

// 全局前置守卫
router.beforeEach((to, from, next) => {
  const token = localStorage.getItem('token')
  
  // 如果路由需要鉴权且没有token,跳转到登录页
  if (to.meta.requiresAuth && !token) {
    next('/login')
  } 
  // 如果已经登录又访问登录页,跳转到首页
  else if (to.name === 'Login' && token) {
    next('/')
  } 
  // 其他情况正常放行
  else {
    next()
  }
})

export default router

方法二:白名单模式

// router/index.js
// 定义不需要鉴权的路由名称白名单
const whiteList = ['Login', 'Register', 'NotFound']

router.beforeEach((to, from, next) => {
  const token = localStorage.getItem('token')
  
  // 如果在白名单中,直接放行
  if (whiteList.includes(to.name)) {
    next()
    return
  }
  
  // 不在白名单且没有token,跳转到登录页
  if (!token) {
    next('/login')
  } 
  // 有token正常放行
  else {
    next()
  }
})

方法三:反向逻辑(默认需要鉴权)

// 在路由meta中明确标记不需要鉴权的路由
const routes = [
  {
    path: '/login',
    name: 'Login',
    component: () => import('@/views/Login.vue'),
    meta: {
      noAuth: true // 明确标记不需要鉴权
    }
  }
]

router.beforeEach((to, from, next) => {
  const token = localStorage.getItem('token')
  
  // 如果路由不要求免鉴权且没有token,跳转到登录页
  if (!to.meta.noAuth && !token) {
    next('/login')
  } 
  // 免鉴权路由或已登录用户正常放行
  else {
    next()
  }
})

方法四:动态路由 + 鉴权分离

对于更复杂的场景,可以将路由分为常驻路由和动态路由:

// 常驻路由(不需要鉴权)
const constantRoutes = [
  {
    path: '/login',
    name: 'Login',
    component: () => import('@/views/Login.vue')
  }
]

// 需要鉴权的动态路由
const asyncRoutes = [
  {
    path: '/dashboard',
    name: 'Dashboard',
    component: () => import('@/views/Dashboard.vue')
  }
]

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

// 登录后添加动态路由
export function addRoutes() {
  asyncRoutes.forEach(route => {
    router.addRoute(route)
  })
}

// 全局前置守卫
router.beforeEach((to, from, next) => {
  const token = localStorage.getItem('token')
  
  // 检查路由是否存在
  if (!router.hasRoute(to.name)) {
    if (token) {
      addRoutes()
      next(to.fullPath) // 重定向到原路径
    } else {
      next('/login')
    }
  } else {
    next()
  }
})

最佳实践建议

  1. 统一鉴权逻辑:选择一种方式并在整个项目中保持一致
  2. 路由懒加载:使用动态导入(() => import())优化性能
  3. 错误处理:添加404页面处理未匹配路由
  4. Token存储:考虑使用更安全的存储方式如httpOnly cookie
  5. 路由元信息扩展:可以扩展meta对象包含更多权限信息,如角色权限等
meta: {
  requiresAuth: true,
  roles: ['admin', 'editor']
}

通过以上方法,你可以灵活地控制哪些路由需要鉴权,哪些路由可以直接访问。