
Vue 全局守卫结合addRoute实现路由权限控制
在实现全局守卫时,需要确保 token 存储的正确性,避免 CSRF攻击 addRoutes 方法需要在路由初始化后调用,确保动态路由正确挂载 generateMenu 方法需要根据实际项目菜单结构进行调整 在实际应用中,建议增加更多的权限校验逻辑,确保敏感路由的访问权限
发布日期:2021-05-10 02:09:16
浏览次数:29
分类:精选文章
本文共 3479 字,大约阅读时间需要 11 分钟。
前端与后端协同实现路由权限控制
在现代单页应用开发中,路由权限控制是保障应用安全的重要环节。本文将详细阐述如何通过前端路由和全局守卫实现动态路由权限控制,以及如何通过addRoute实现路由的动态挂载。
全局守卫与addRoute的应用
在前端路由中,权限控制通常通过全局守卫和路由动态挂载来实现。以下是具体实现步骤:
1. 初始化基础路由
在应用启动之前,需要先初始化不需要权限控制的路由。这些包括登录页面、404错误页面等。例如:
// router.jsimport Vue from 'vue';import VueRouter from 'vue-router';import Layout from '../views/layout/Layout';Vue.use(VueRouter);const routes = [ { path: '/login', name: 'login', component: () => import('../views/login/login') }, { path: '/404', name: '404', component: () => import('../views/errorPage/404') }];const router = new VueRouter({ mode: 'history', base: '/sdd/', routes});export default router;
2. 全局路由守卫结合addRoute实现动态控制
通过全局守卫,可以在每次路由跳转前后执行权限校验逻辑。具体实现如下:
// permission.jsimport router from './router';import NProgress from 'nprogress';import store from './store';import { generateMenu } from './views/layout/components/utils/menu';NProgress.configure({ showSpinner: false });const whiteList = ['/login'];router beforeEach 导航钩子中,实现权限校验:router beforeEach((to, from, next) => { NProgress.start(); if (sessionStorage.token) { if (to.path === '/login') { next({ path: '/' }); NProgress.done(); } else { // 判断用户是否已登录 if (from.path === '/login' || !store.state.user.userInfo.username) { const res = await store.dispatch('user/getUserInfo'); if (res.code !== 0) { if (res.code !== 5002) { sessionStorage.removeItem('token'); next({ path: '/login' }); NProgress.done(); } } else { // 获取用户权限 if (store.state.user.routes.length === 0) { const routes = await store.dispatch('user/listMenus'); if (routes.length > 0) { store.dispatch('user/setRoutes', generateMenu(routes) || []); router.addRoutes([...routes, { path: '*', redirect: '/404' }]); next({ ...to, replace: true }); } } else { next(); } } } else { next(); } } } else { if (whiteList.includes(to.path)) { next(); } else { next({ path: '/login' }); NProgress.done(); } } NProgress.done();});router afterEach(() => { NProgress.done();});
3. generateMenu 方法实现
generateMenu 方法用于将后端返回的菜单数据转换为前端路由定义:
import Layout from '../../Layout';const menuMap = { // 请参考实际项目中的菜单结构 // ...};export function generateMenu(menu) { const travelMenu = (menuItems) => { const routes = []; for (const item of menuItems) { const route = {}; route.name = item.moduleName; route.path = menuMap[item.moduleId]?.path || '/'; route.component = menuMap[item.moduleId]?.component || Layout; route.icon = menuMap[item.moduleId]?.icon || 'menu'; if (item.childModules && item.childModules.length > 0) { route.children = travelMenu(item.childModules); } if (route.path && route.component) { routes.push(route); } } // 添加重定向 routes.forEach((item) => { if (item.path === '/') { item.redirect = '/dashboard'; item.children = [{ path: 'dashboard', component: () => import('../../../dashboard/dashboard'), name: item.name }]; } else if (item.children) { item.redirect = `${item.path}/${item.children[0].path}`; } }); return routes; }; return travelMenu(menu);}
注意事项
通过以上方法,可以实现前端路由的动态权限控制,确保应用的安全性和可维护性。